Unsupported operand types in if/else list comprehension
Hello all, I have a question about the if/else aspect of list comprehension: I would like to go through a list and place quotes around an item if it is a string, and keep the item the same if it's anything else: e.g.['a',9,'8b'] --> ['"a"', 9, '"8b"'] I understand that if/else list comprehension should be generally: b=[(F,T)[boolean test] for val in X] so, I tried the following code: a=['test',1,'two'] b=[(inst, '"'+inst+'"')[isinstance(inst, str)] for inst in a] I end up getting the error: unsupported operand type(s) for +: 'int' and 'str' >From playing around with other examples, I get the feeling that Python is calculating both values (inst and '"'+inst+'"') before selecting which one to pass to the new list. Am I right? Is there any way I can do this using list comprehension? Thanks in advance, Michael -- http://mail.python.org/mailman/listinfo/python-list
Re: Unsupported operand types in if/else list comprehension
Thanks to all of you. FYI, I'm doing this because I'm working on creating some insert statements in SQL, where string values need to be quoted, and integer values need to be unquoted. I wanted to be sure that I could pass these values to the list in a normal way e.g. ['test', 1, 'two'] and have a function correct the list for me, rather than calling the function with a strangely quoted list e.g. ['"'test'"', 1, '"'two'"']. Again, thanks. On Fri, Apr 10, 2009 at 5:18 PM, John Yeung wrote: > On Apr 10, 5:07 pm, Mike H wrote: >> From playing around with other examples, I get the feeling >> that Python is calculating both values (inst and '"'+inst+'"') >> before selecting which one to pass to the new list. Am I right? > > I believe so. (I'm sure the experts here will tell you more > definitively.) > >> Is there any way I can do this using list comprehension? > > Yes. If you are using 2.5 or later, you can do this: > > Python 2.6.1 (r261:67517, Dec 4 2008, 16:51:00) [MSC v.1500 32 bit > (Intel)] on > win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> a=['test',1,'two'] >>>> b=[(x if not isinstance(x, str) else '"'+x+'"') for x in a] >>>> b > ['"test"', 1, '"two"'] >>>> > > If you are trying to make a CSV file, then even better may be to use > the csv module. > > John > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Unsupported operand types in if/else list comprehension
Ok, thanks again to everyone for their suggestions, even if it appears I was going down the wrong path at the start. I'm a grad student creating this database to hold some of my own research on an isolated server, so security, etc. isn't my biggest concern -- but I would like to do this right. Here's the code that I've come up with now. Although it's gotten away from the original question, those that have commented on this seem to have some SQL knowledge, so I'd like to run it by them to see if this is better in theory. (I've tried it and it works in practice!) FYI, I'm using MySQLdb to connect with the Database. Also, I realize I should probably add in some try/catch statements and other error handling... but this is what I have at the moment. def insert_cmd(myTable, myFields, myValues, myReturnKey): """Imports given fields and values into a given table, returns an SQL variable holding the Autoincrement key""" #tests to see if myParentKey is valid in mySQL. if not myReturnKey.startswith("@"): print "Error, myReturnKey must start with '@'"; sys.exit() SQLcmd="INSERT INTO " + myTable + " (%s) " % ", ".join(myFields) SQLcmd=SQLcmd + "VALUES (%s,%s,%s);" cursor.execute(SQLcmd, (myValues)) #sets and returns SQL variable. SQLcmd="select " + myReturnKey + ":=last_insert_id();" cursor.execute(SQLcmd) return myReturnKey On Sat, Apr 11, 2009 at 7:38 AM, Diez B. Roggisch wrote: > Mike H schrieb: >> >> Thanks to all of you. >> >> FYI, I'm doing this because I'm working on creating some insert >> statements in SQL, where string values need to be quoted, and integer >> values need to be unquoted. >> >> I wanted to be sure that I could pass these values to the list in a >> normal way e.g. ['test', 1, 'two'] and have a function correct the >> list for me, rather than calling the function with a strangely quoted >> list e.g. ['"'test'"', 1, '"'two'"'].> > > Don't do that yourself. This is error-prone. Instead, use the parametrized > verison of the cursor.execute-method. It will perform the necessary > escaping, and depending on the database and database adapter you use better > performance. > > Diez > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Unsupported operand types in if/else list comprehension
Well, I'm an idiot. Obviously, the line "VALUES (%s, %s, %s);" needs to be modified to adapt for the number of arguments in the list. But otherwise On Sat, Apr 11, 2009 at 11:28 AM, Mike H wrote: > Ok, thanks again to everyone for their suggestions, even if it appears > I was going down the wrong path at the start. I'm a grad student > creating this database to hold some of my own research on an isolated > server, so security, etc. isn't my biggest concern -- but I would like > to do this right. Here's the code that I've come up with now. Although > it's gotten away from the original question, those that have commented > on this seem to have some SQL knowledge, so I'd like to run it by them > to see if this is better in theory. (I've tried it and it works in > practice!) > > FYI, I'm using MySQLdb to connect with the Database. > > Also, I realize I should probably add in some try/catch statements and > other error handling... but this is what I have at the moment. > > > > def insert_cmd(myTable, myFields, myValues, myReturnKey): > """Imports given fields and values into a given table, returns an > SQL variable holding the Autoincrement key""" > > #tests to see if myParentKey is valid in mySQL. > if not myReturnKey.startswith("@"): print "Error, myReturnKey must > start with '@'"; sys.exit() > > SQLcmd="INSERT INTO " + myTable + " (%s) " % ", ".join(myFields) > SQLcmd=SQLcmd + "VALUES (%s,%s,%s);" > cursor.execute(SQLcmd, (myValues)) > > #sets and returns SQL variable. > SQLcmd="select " + myReturnKey + ":=last_insert_id();" > cursor.execute(SQLcmd) > return myReturnKey > > > On Sat, Apr 11, 2009 at 7:38 AM, Diez B. Roggisch wrote: >> Mike H schrieb: >>> >>> Thanks to all of you. >>> >>> FYI, I'm doing this because I'm working on creating some insert >>> statements in SQL, where string values need to be quoted, and integer >>> values need to be unquoted. >>> >>> I wanted to be sure that I could pass these values to the list in a >>> normal way e.g. ['test', 1, 'two'] and have a function correct the >>> list for me, rather than calling the function with a strangely quoted >>> list e.g. ['"'test'"', 1, '"'two'"'].> >> >> Don't do that yourself. This is error-prone. Instead, use the parametrized >> verison of the cursor.execute-method. It will perform the necessary >> escaping, and depending on the database and database adapter you use better >> performance. >> >> Diez >> -- >> http://mail.python.org/mailman/listinfo/python-list >> > -- http://mail.python.org/mailman/listinfo/python-list
Re: Unsupported operand types in if/else list comprehension
Sigh. One more. And again, thank you for all of the help. I realized that the last version that I posted took care of an SQL injection problem for the values, but not for the fields. So, I went ahead and modified the code: def new_insert_cmd(myTable, myFields, myValues): """Imports given fields and values into a given table, returns the Autoincrement value.""" SQLcmd="INSERT INTO " + myTable + " ( " + create_input_string(myFields) + " ) VALUES ( " \ + create_input_string(myValues) +" );" allArguments=myFields+myValues cursor.execute(SQLcmd, (allArguments)) create_input_strings() is just a function that creates the necessary number of %s's for a given list (and which I'm sure there's a faster way to code): def create_input_string(myList): sOut="" for var in myList: sOut=sOut+"%s, " return sOut[:-2] However, now the cursor.execute statement won't work. I've looked at the content of SQLcmd and the values of allArguments and they seem fine. I've even tried running this at the IDLE command line: cursor.execute("INSERT INTO plan (%s, %s, %s) VALUES (%s, %s, %s);", (["name", "fileno", "size", "Test", "AAA-000", 7])) and I get this error: File "C:\Python25\lib\site-packages\MySQLdb\cursors.py", line 166, in execute self.errorhandler(self, exc, value) File "C:\Python25\lib\site-packages\MySQLdb\connections.py", line 35, in defaulterrorhandler raise errorclass, errorvalue ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''name', 'fileno', 'size') VALUES ('Test', 'AAA-000', 7)' at line 1") Can I not use the cursor.execute command to pass variables that aren't immediately next to each other? If so, is there a better way to go about solving this problem? Again, thanks for your patience and help with a newbie. Michael On Sat, Apr 11, 2009 at 11:53 AM, Mike H wrote: > Well, I'm an idiot. Obviously, the line "VALUES (%s, %s, %s);" needs > to be modified to adapt for the number of arguments in the list. But > otherwise > > On Sat, Apr 11, 2009 at 11:28 AM, Mike H wrote: >> Ok, thanks again to everyone for their suggestions, even if it appears >> I was going down the wrong path at the start. I'm a grad student >> creating this database to hold some of my own research on an isolated >> server, so security, etc. isn't my biggest concern -- but I would like >> to do this right. Here's the code that I've come up with now. Although >> it's gotten away from the original question, those that have commented >> on this seem to have some SQL knowledge, so I'd like to run it by them >> to see if this is better in theory. (I've tried it and it works in >> practice!) >> >> FYI, I'm using MySQLdb to connect with the Database. >> >> Also, I realize I should probably add in some try/catch statements and >> other error handling... but this is what I have at the moment. >> >> >> >> def insert_cmd(myTable, myFields, myValues, myReturnKey): >> """Imports given fields and values into a given table, returns an >> SQL variable holding the Autoincrement key""" >> >> #tests to see if myParentKey is valid in mySQL. >> if not myReturnKey.startswith("@"): print "Error, myReturnKey must >> start with '@'"; sys.exit() >> >> SQLcmd="INSERT INTO " + myTable + " (%s) " % ", ".join(myFields) >> SQLcmd=SQLcmd + "VALUES (%s,%s,%s);" >> cursor.execute(SQLcmd, (myValues)) >> >> #sets and returns SQL variable. >> SQLcmd="select " + myReturnKey + ":=last_insert_id();" >> cursor.execute(SQLcmd) >> return myReturnKey >> >> >> On Sat, Apr 11, 2009 at 7:38 AM, Diez B. Roggisch >> wrote: >>> Mike H schrieb: >>>> >>>> Thanks to all of you. >>>> >>>> FYI, I'm doing this because I'm working on creating some insert >>>> statements in SQL, where string values need to be quoted, and integer >>>> values need to be unquoted. >>>> >>>> I wanted to be sure that I could pass these values to the list in a >>>> normal way e.g. ['test', 1, 'two'] and have a function correct the >>>> list for me, rather than calling the function with a strangely quoted >>>> list e.g. ['"'test'"', 1, '"'two'"'].> >>> >>> Don't do that yourself. This is error-prone. Instead, use the parametrized >>> verison of the cursor.execute-method. It will perform the necessary >>> escaping, and depending on the database and database adapter you use better >>> performance. >>> >>> Diez >>> -- >>> http://mail.python.org/mailman/listinfo/python-list >>> >> > -- http://mail.python.org/mailman/listinfo/python-list
Re: Unsupported operand types in if/else list comprehension
George, I'd love to. Can you give me an idea of where to start looking? I've gone through a couple of books, and Googled a ton of websites. Maybe I'm just not using the right terms. My background is definitely not CompSci. But if you'd give me a suggestion of where to look, I'd appreciate it. Thanks, On Sat, Apr 11, 2009 at 4:18 PM, George Sakkis wrote: > On Apr 11, 3:03 pm, Mike H wrote: > >> Can I not use the cursor.execute command to pass variables that aren't >> immediately next to each other? If so, is there a better way to go >> about solving this problem? > > Yes, there is. Use one of the several production quality python SQL > toolkits built for exactly this purpose instead of putting together an > ad-hoc, informally-specified bug-ridden slow implementation of half of > their feature set. > > George > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: How to sort this without 'cmp=' in python 3?
On Saturday, October 15, 2016 at 12:27:42 AM UTC-7, Peter Otten wrote: > 38016...@gmail.com wrote: > > > nums=['3','30','34','32','9','5'] > > I need to sort the list in order to get the largest number string: > > '953433230' > > > > nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True) > > > > But how to do this in python 3? > > > > Thank you > While cmp_to_key is neat doing it by hand should also be instructive. > Essentially you move the comparison into a method of the key: > > $ cat translate_cmp.py > class Key(str): > def __lt__(a, b): > return a + b < b + a > > nums = ['3','30','34','32','9','5'] > print(nums) > nums.sort(key=Key, reverse=True) > print(nums) > print("".join(nums)) > > $ python3 translate_cmp.py > ['3', '30', '34', '32', '9', '5'] > ['9', '5', '34', '3', '32', '30'] > 953433230 > > The above works because in CPython list.sort() currently uses only the < > operator; adding __gt__() and __eq__() to make this portable is > straightforward even if you do not use the functools.total_ordering class > decorator. Is it possible to use lambda expression instead of defining a `Key` class? Something like `sorted(my_list, key = lambda x, y: x+y > y+x)`? -- https://mail.python.org/mailman/listinfo/python-list