How to unpack only some arguments from zip, not all? - python

My sql query:
select id,value,zvalue from axis
gives me result like this:
ans=(1,23,34)(12,34,35)(31,67,45)(231,3412,234)
now if i want all these 3 variables as 3 different lists
id,value,zvalue=zip(*ans)
it will give me 3 separate lists.
but if i only want id and value as separate lists.It will give me TOO MANY VALUES TO UNPACK ERROR.
id,value =zip(*ans)
is there any way where i can create any number of lists from sql query.because if there are 10 parameters in the query , i have to use all the parameters while using ZIP???
please help

The number of arguments must match, this is a rule in Python 2. For Python 3, you can use * to capture into a list.
The common pythonic (2.x) workaround is to use _ to denote variables you won't use, i.e.:
id,value,_ = zip(*ans) # only works for exactly three values
As DSM commented, for Python 3, you can use * to grab "remaining" args as a list:
id, value, *_ = zip(*ans) # _ will be a list of zero or more args
Or, simplest, just slice the return from zip:
id,value = zip(*ans)[:2] # ignore all but first two values

If you are using Python 3 you can use this for unpacking n additional elements:
In [0]: a, b, *_ = (1, 2, 3, 4)
In [1]: a
1

I think you might be looking for something like this:
ids = [t[0] for t in ans]
values = [t[1] for t in ans]
The first list comprehension gets the first column in all tuples in ans, that is, the id column. The second list comprehension gets the second column for all tuples in ans, that is, the value column.

Related

Select columns in pyrhon based on a condition

I am new to Python!
I have an input vector of p. I am trying to select columns of p such that p(i)>2 and put them into a new vector y. e.g. something like below which by the way, gives error:
y=(p[i]>2)
If I understand correctly, your question is not about Pandas Dataframe, rather about regular Python List. If so, you can use list comprehension.
A list comprehension is a short syntax for iterating through a list and picking the elements that satisfy a certain condition.
Let's see first how you can accomplish what you want with a regular for loop (the non-pythonic way):
my_list = [1, 4, 6, 1, 0]
my_new_list = []
for n in my_list:
if n > 2:
my_new_list.append(n)
Now, Python makes such a selection of elements from a list very easy using the list comprehension syntax:
my_new_list = [n for n in my_list if n > 2]
where the first n refers to what we append to my_new_list, then comes the for loop and finally the filtering condition.
In python you have to select give the column name value inside the bracket so you need to give the column name first and then you will be able to acces that column and then condition will be working fine. LIke this:
y = dataframe[p['i'] > 80]
and also you will be getting a column which will be taken as dataframe. visit this website for more information.

Get the remaining value from list of possible values (inline if possible)

I have 3 integers in a list (0,1,2) and ask the user to set these values to 3 different objects. I want the third item to be autoassigned as simply as possible. I'd like to reference these objects as stacks[stack_something]:
# list of stack - one source, one target, one helper
stacks = (
Stack(),
Stack(),
Stack()
)
# 3 variables that point to indexes in 'stacks'
stack_s = userSet() # user chooses which is the source (input)
stack_t = userSet() # user chooses which is the target (output)
stack_h = [0,1,2].remove(stack_in).remove(stack_to).pop() # something like this
Let's say user chooses 1, then 3. So stack_h should automatically get 2.
You can try this:
stack_h = (set([0,1,2])-{stack_s, stack_t}).pop()
Here the outer parenthesis is just used as enclosers, on which .pop() operates. The curly braces signify sets. And set() call converts the list to a set. Just like [] is used for list, () is used for tuple, {} is used for set and dictionary.
A difference between set and dictionary is:
# set
s = {1,2,3}
# dictionary
d = {'a':1, 'b':2, 'c':3}
So dictionary are collection of values with unique keys.
sets are collection of unordered unique elements, very handy for membership checking, and are normally faster than list methods in these cases. I would suggest you to look up sets.
This could also work for you:
stacks = [0, 1, 2]
stack_s = int(input('stack_s'))
stack_t = int(input('stack_t'))
stack_h = [x for x in stacks if x not in [stack_s, stack_t]][0]
print(stack_h)

Initialize a list using inline for loop

I am initializing my list object using following code.
list = [
func1(centroids[0],value),
func1(centroids[1],value),
....,
func1(centroids[n],value)]
I am trying to do it a more elegant way using some inline iteration. Following is the pseudo code of one possible way.
list = [value for value in func1(centroids[n],value)]
I am not clear how to call func1 in an iterative way. Can you suggest a possible implementation?
For a list of objects, Python knows how to iterate over it directly so you can eliminate the index shown in most of the other answers,
res = [func1(c, value) for c in centroids]
That's all there is to it.
A simple list comprehension consists of the "template" list element, followed by the iterator needed to step through the desired values.
my_list = [func1(centroids[0],value)
for n in range(n+1)]
Use this code:
list = [func1(centroids[x], value) for x in range(n)]
This is called a list comprehension. Put the values that you want the list to contain up front, then followed by the for loop. You can use the iterating variable of the for loop with the value. In this code, you set up n number(s) of variable(s) from the function call func1(centroids[x], value). If the variable n equals to, let's say, 4, list = [func1(centroids[0], value), func1(centroids[0], value), func1(centroids[0], value), func1(centroids[0], value)] would be equal to the code above

Python convert list of tuples into single tuple

Is there a way to convert a list of tuples into a single tuple? I have received a list of tuples from cursor.fetchall() but would like to make this into a single tuple:
curr_table_columns = cursor.fetchall()
For example:
[(u'w_id',), (u'w_name',), (u'w_street',)]
becomes
[(u'w_id', u'w_name', u'w_street')]
With itertools.chain, it's trivial. from itertools import chain and you can do either:
[tuple(chain.from_iterable(curr_table_columns))]
or:
[tuple(chain(*curr_table_columns))]
The former is preferred for long or unbounded iterable inputs (though don't wrap in tuple for unbounded!); for a small input (particularly one that's already a list or tuple), the latter is slightly slower, but fine. Either one is going to be significantly faster than a genexpr and indexing for inputs of any size at all.
Try this:
a=[(u'w_id',), (u'w_name',), (u'w_street',)]
print [tuple([i[0] for i in a])]
Output:
[(u'w_id', u'w_name', u'w_street')]
Not efficient*, but it is simple:
>>> ts = [(u'w_id',), (u'w_name',), (u'w_street',)]
>>> sum(ts, ())
('w_id', 'w_name', 'w_street')
So, just wrap it in a list if you must:
>>> result = [sum(ts, ())]
>>> result
[('w_id', 'w_name', 'w_street')]
*Warning: scales quadratically. Some might be inclined to let is slide for joining some column names into a single container. Definitely don't try to process millions of tuples this way.
Use itertools solution for linear time.
This function can convert listWidgets item into single tuple and also convert multiple element of tuple into single element tuple : Used for Sqlite3 and data query from listwidgets.
def tuple_converter(self,item):
target = ''
for i in item:
target += i + " "
target = target.rstrip()
target = tuple(target.split(","))
return target
#syntax name = tuple_converter(tuple((item).split()))
'''

Python: Sorting a list by class objects

Working on a project for CS1, and I am close to cracking it, but this part of the code has stumped me! The object of the project is to create a list of the top 20 names in any given year by referencing a file with thousands of names on it. Each line in each file contains the name, gender, and how many times it occurs. This file is seperated by gender (so female names in order of their occurences followed by male names in order of their occurences). I have gotten the code to a point where each entry is contained within a class in a list (so this list is a long list of memory entries). Here is the code I have up to this point.
class entry():
__slots__ = ('name' , 'sex' , 'occ')
def mkEntry( name, sex, occ ):
dat = entry()
dat.name = name
dat.sex = sex
dat.occ = occ
return dat
##test = mkEntry('Mary', 'F', '7065')
##print(test.name, test.sex, test.occ)
def readFile(fileName):
fullset = []
for line in open(fileName):
val = line.split(",")
sett = mkEntry(val[0] , val[1] , int(val[2]))
fullset.append(sett)
return fullset
fullset = readFile("names/yob1880.txt")
print(fullset)
What I am wondering if I can do at this point is can I sort this list via usage of sort() or other functions, but sort the list by their occurrences (dat.occ in each entry) so in the end result I will have a list sorted independently of gender and then at that point I can print the first entries in the list, as they should be what I am seeking. Is it possible to sort the list like this?
Yes, you can sort lists of objects using sort(). sort() takes a function as an optional argument key. The key function is applied to each element in the list before making the comparisons. For example, if you wanted to sort a list of integers by their absolute value, you could do the following
>>> a = [-5, 4, 6, -2, 3, 1]
>>> a.sort(key=abs)
>>> a
[1, -2, 3, 4, -5, 6]
In your case, you need a custom key that will extract the number of occurrences for each object, e.g.
def get_occ(d): return d.occ
fullset.sort(key=get_occ)
(you could also do this using an anonymous function: fullset.sort(key=lambda d: d.occ)). Then you just need to extract the top 20 elements from this list.
Note that by default sort returns elements in ascending order, which you can manipulate e.g. fullset.sort(key=get_occ, reverse=True)
This sorts the list by using the occ property in descending order:
fullset.sort(key=lambda x: x.occ, reverse=True)
You mean you want to sort the list only by the occ? sort() has a parameter named key, you can do like this:
fullset.sort(key=lambda x: x.occ)
I think you just want to sort on the value of the 'occ' attribute of each object, right? You just need to use the key keyword argument to any of the various ordering functions that Python has available. For example
getocc = lambda entry: entry.occ
sorted(fullset, key=getocc)
# or, for in-place sorting
fullset.sort(key=getocc)
or perhaps some may think it's more pythonic to use operator.attrgetter instead of a custom lambda:
import operator
getocc = operator.attrgetter('occ')
sorted(fullset, key=getocc)
But it sounds like the list is pretty big. If you only want the first few entries in the list, sorting may be an unnecessarily expensive operation. For example, if you only want the first value you can get that in O(N) time:
min(fullset, key=getocc) # Same getocc as above
If you want the first three, say, you can use a heap instead of sorting.
import heapq
heapq.nsmallest(3, fullset, key=getocc)
A heap is a useful data structure for getting a slice of ordered elements from a list without sorting the whole list. The above is equivalent to sorted(fullset, key=getocc)[:3], but faster if the list is large.
Hopefully it's obvious you can get the three largest with heapq.nlargest and the same arguments. Likewise you can reverse any of the sorts or replace min with max.

Categories

Resources