I get the empty set when using the for loop - python

I know this must be something very basic, but I dont know why I keep getting an empty set. What should I do in order to not get an empty set?
s=set()
for a in [(1,2),(1,3),(1,2)]:
b=[]
for j in range(len(a)-1):
b.append(a)
s.union(b)
print(s)
I get:
s=([])
but the result I want is
{(1,2),(1,3)}
I know there is another way to take the union, but I wish to do so with this for loop.

Try this:
s = set()
s = s.union([(1,2),(1,3),(1,2)])
set.union doesn't modify the set, so you need to save the result
if you want to use a for-loop, as you did in your post, then make sure to save the result of the union: s = s.union(b)

The function union returns a set that is the union of s with b, you should change your code to:
s = set()
for a in [(1, 2), (1, 3), (1, 2)]:
b = []
for j in range(len(a) - 1):
b.append(a)
s = s.union(b)
print(s)
Output
{(1, 2), (1, 3)}
As an alternative you can use the update function:
s.update(b)
Output
{(1, 2), (1, 3)}

You only need the union method if you want to union two non-empty sets. Since you start with an empty set, you can simply use the set constructor:
s = set([(1,2),(1,3),(1,2)])
and s would become:
{(1, 2), (1, 3)}

Related

Python print statement prints address instead of value

This is the code which I have did
from itertools import product
lst1=list(map(int,input().split()))
lst2=list(map(int,input().split()))
l3=product(lst1,lst2)
Input:
1 2
2 3
Output:
<itertools.product object at 0x7f02bdedb500>
Output that I want:
(1, 3) (1, 4) (2, 3) (2, 4)
I have tried adding parentheses, brackets and also tried to store the value in a variable and printed it. I still couldn't able to get that output. I don't want the output as a list, the expected output is shown above.
product(lst1,lst2) returns a itertools.product object just use map function to update internal tuple 1st index item or iterate though each element.
So use map function and update each tuple by 1 using lambda function :
l3= list(map(lambda i: (i[0], i[-1]+1), product(lst1,lst2)))
print(l3)
OUTPUT :
[(1, 3), (1, 4), (2, 3), (2, 4)]
Problem with this output is that it is string representation of list object so the best way is to go with this method.
So use iterate though this iterable object :
for i in l3:
i = list(i)
i[-1] += 1
print(tuple(i), end=' ')
OUTPUT :
(1, 3) (1, 4) (2, 3) (2, 4)
Convert or cast it to list, it works.
from itertools import product
lst1=list(map(int,input().split()))
lst2=list(map(int,input().split()))
l3=list(product(lst1,lst2))
"itertools.product" returns a generator, to get the list output you need :
list(l3)
However, not sure where you got your values from, I got :
[(1, 2), (1, 3), (2, 2), (2, 3)]
You can iterate l3 to get the desired output:
for i in l3:
print(i, end=" ")

Using enumerate() to enumerate items with letters rather than numbers

I'm trying to use the built-in function enumerate() to label some points or vertices where each point is represented by its coordinates in a list(or set) of tuples which essentially looks like {(4,5), (6,8), (1,2)}
I want to assign a letter starting from "a" in ascending order to each tuple in this set, using enumerate() does exactly the same but It's written in a way that it returns the value of the index of each item so that it's a number starting from 0.
is there any way to do it other than writing my own enumerate()?
Check this out:
import string
tup = {(4,5), (6,8), (1,2)}
dic = {i: j for i, j in zip(string.ascii_lowercase, tup)}
This returns:
{'a': (4, 5), 'b': (6, 8), 'c': (1, 2)}
This is enumerate's signature.
enumerate(iterable, start=0)
Use start as 65 for 'A' and 97 for 'a'.
lst=[(1,2),(2,3),(3,4),...]
for idx,val in enumerate(lst,65):
print(chr(idx),val)
A (1, 2)
B (2, 3)
C (3, 4)
Maybe this is a way to get what you want, using chr():
L = [(4,5), (6,8), (1,2)]
for k, v in enumerate(L):
print(chr(65 + k), v)
Output :
A (4, 5)
B (6, 8)
C (1, 2)
The enumerate function is defined as follow :
enumerate(iterable, start=0)
I think just have to write your own enumerate or an wrapper around enumerate.

Is There A Universal Selector Option For if...in Clauses?

I have a "large" list of tuples:
thelist=[(1,2),(1,3),(2,3)]
I want to check whether any tuple in the list starts with a 1, and if it does, print "aaa":
for i in thelist:
templist.append((i[0],i))
for i in templist:
if i[0]==1:
print("aaa")
break
Which is rather ardurous as I have to create the templist. Is there any way I can do this:
if (1,_) in thelist:
print("aaa")
Where _ is the universal selector. Note that the list would be very large and thus it is very costly to implement another list.
There isn't, although you can just use any
any(i[0] == 1 for i in thelist) --> Returns true if the first element is 1
If you don’t actually need the actual tuple, like you do in your example, then you can actually use tuple unpacking for exactly that purpose:
>>> the_list = [(1, 2), (1, 3), (2, 3)]
>>> for x, y in the_list:
if x == 1:
print('aaa')
break
aaa
If you add a * in front of the y, you can also unpack tuples of different sizes, collecting the remainder of the tuple:
>>> other_list = [(1, 2, 3, 4, 5), (1, 3), (2, 3)]
>>> for x, *y in other_list:
if x == 1:
print(y)
break
[2, 3, 4, 5]
Otherwise, if you just want to filter your list based on some premise and then do something on those filtered items, you can use filter with a custom function:
>>> def startsWithOne(x):
return x[0] == 1
>>> thelist = [(1, 2), (1, 3), (2, 3)]
>>> for x in filter(starts_with_one, the_list):
print(x)
(1, 2)
(1, 3)
This is probably the most flexible way which also avoids creating a separate list in memory, as the elements are filtered lazily when you interate the list with your loop.
Finally, if you just want to figure out if any of your items starts with a 1, like you do in your example code, then you could just do it like this:
>>> if any(filter(starts_with_one, the_list)):
print('aaa')
aaa
But I assume that this was just an oversimplified example.

How to sort dictionary on first element of the key (tuple)

I have a dictionary where each key is a tuple of values, I want to use the sorted() method to sort the dictionary on the very first element of my tuple. My code looks like this:
def mapData(header_list, dict_obj):
master_dict = {}
client_section_list = []
for element in header_list:
for row in dict_obj:
if (row['PEOPLE_ID'], row['DON_DATE']) == element:
client_section_list.append(row)
element = list(element)
element_list = [client_section_list[0]['DEDUCT_AMT'],
client_section_list[0]['ND_AMT'],
client_section_list[0]['DEDUCT_YTD'],
client_section_list[0]['NONDEDUCT_YTD']
]
try:
element_list.append((float(client_section_list[0]['DEDUCT_YTD']) +
float(client_section_list[0]['NONDEDUCT_YTD'])
))
except ValueError:
pass
element.extend(element_list)
element = tuple(element)
master_dict[element] = client_section_list
client_section_list = []
return sorted(master_dict, key=lambda key: key[master_dict[(1)]]
The last line is where I'm trying to find a way to sort it. My tuple looks like this:
(312178078,6/22/15,25,0,25,0,25.0)
Not entirely sure what you are trying to do, particularly what that function is supposed to return. I assume that you want to return the dictionary sorted by the first element in the key-tuples.
For this, there are two things to note:
Tuples are by default sorted by their first element (and if those are the same, then by the second, and so on), so no special key function is required
Regular dictionaries are unordered, i.e. they can not be permanently sorted in any order; you can only sort their items as a list, or use that list to create an OrderedDict instead
Some minimal example:
>>> d = {(2,4): 1, (1,3): 2, (1,2): 3, (3,1): 4}
>>> sorted(d)
[(1, 2), (1, 3), (2, 4), (3, 1)]
>>> sorted(d.items())
[((1, 2), 3), ((1, 3), 2), ((2, 4), 1), ((3, 1), 4)]
>>> collections.OrderedDict(sorted(d.items()))
OrderedDict([((1, 2), 3), ((1, 3), 2), ((2, 4), 1), ((3, 1), 4)])
In your case, you probably want this:
return collections.OrderedDict(sorted(master_dict.items()))
As #tobias_k has mentioned, sorted sorts tuples by its elements with decreasing priority, e.g. if you take a tuple (a, b, c) the highest sorting priority goes to a, then goes b etc (by default sorted uses object's comparison methods and this is how tuple comparison works). So sorted(master_dict) is all you need if you want a list of sorted keys, yet I believe you really want to leave the values
sorted(master_dict.items(), key=lambda key: key[0])
dict.items returns tuples of form (key, value) so here you need to specify the sorting key.

Simple List Error Python

In the following code, I created a list of lists, like an array. I began getting a "list assignment out of range" error. As a workaround for this error, I added 2 extra instances of diceSumTable, is you can see in the code. It will print now, but it is preceded by "2, 3". In my studying, I can't recall any reason why this would be happening if every instance of diceSumTable is already defined.
EDIT: Here was the original code, without applying the workaround.
def dice():
diceSumTable = [2,3,4,5,6,7,8,9,10,11,12]
diceSumTable[2] = [(1,1)]
diceSumTable[3] = [(1,2),(2,1)]
diceSumTable[4] = [(1,3),(2,2),(3,1)]
diceSumTable[5] = [(1,4),(2,3),(3,2),(4,1)]
diceSumTable[6] = [(1,5),(2,4),(3,3),(4,2),(5,1)]
diceSumTable[7] = [(1,6),(2,5),(3,4),(4,3),(5,2),(6,1)]
diceSumTable[8] = [(2,6),(3,5),(4,4),(5,3),(6,2)]
diceSumTable[9] = [(3,6),(4,5),(5,4),(6,3)]
diceSumTable[10] = [(4,6),(5,5),(6,4)]
diceSumTable[11] = [(5,6),(6,5)]
diceSumTable[12] = [(6,6)]
#for illustrative purposes
for i in diceSumTable:
print i
dice()
As said, you start indexing the diceSumTable from index #2 onward, leaving entries 0 and 1 untouched. The error you got was because you were indexing past the end of the array.
For your problem a "dict" might be a better solution:
diceSumTable = {}
diceSumTable[ 2 ] = [(1,1)]
diceSumTable[ 3 ] = [(1,2), (2,1)]
Try this:
def dice():
diceSumTable = [] # define diceSumTable as a list
diceSumTable.append((1,1)) # append the tuple to diceSumTable
diceSumTable.append(((1,2),(2,1))) # append a tuple of tuples to diceSumTable
diceSumTable.append(((1,3),(2,2),(3,1)))
diceSumTable.append(((1,4),(2,3),(3,2),(4,1)))
diceSumTable.append(((1,5),(2,4),(3,3),(4,2),(5,1)))
diceSumTable.append(((1,6),(2,5),(3,4),(4,3),(5,2),(6,1)))
diceSumTable.append(((2,6),(3,5),(4,4),(5,3),(6,2)))
diceSumTable.append(((3,6),(4,5),(5,4),(6,3)))
diceSumTable.append(((4,6),(5,5),(6,4)))
diceSumTable.append(((5,6),(6,5)))
diceSumTable.append(((6,6)))
#for illustrative purposes
for i in diceSumTable:
print i
dice()
You got 2, 3 because that's what you entered into the list in the first to places, the other numbers you put in got replaced with statements like diceSumTable[x] =.
You are entering data from 2 index (means third element in array).
diceSumTable = [2,3,4,5,6,7,8,9,10,11,12,13,14]
when you do
# Replacing third element
diceSumTable[2] = [(1,1)]
diceSumTable will be like
diceSumTable = [2,3,[(1,1)],5,6,7,8,9,10,11,12,13,14]
Slly it will replace all values.
You are confusing the value of an entry in a list with the index of a list.
diceSumTable[3] corresponds to the fourth entry in diceSumTable (since they are numbered from 0).
Your first line creates a list diceSumTable with 13 entries, numbered 0...12.
Your next set of lines fills in the 3d through 13th entries (and throws away what was there before!).
To do what you want, you have a few choices.
1/ You can do what you're doing, but ignore the first two entries. This is not very pythonic...
2/ You can create a length 11 list, holding the actual entries. In this case, the most efficient way to do it is
diceSumTable = [] ### empty list
diceSumTable.append([(1,1)])
diceSumTable.append([(1,2),(2,1)])
#### etc.
3/ You can use a dict. This is probably closest to what you want, although it's slightly inefficient in space and time, since you just want consecutive integer keys (but premature optimisation is the root of all evil):
diceSumTable = {} ### empty dict
diceSumTable[2] = [(1,1)]
diceSumTable[3] = [(1,2),(2,1)]
#### etc.
(Markdown question: is there any way to intersperse code within a bulleted or enumerated list?)
When you set diceSumTable[2] you are replacing the third value in the list (lists are zero indexed - first value is name[0]) not the value that currently holds 2.
So after the first call you have diceSumTable equal to [2,3,[(1,1)],5,6,...].
I think what you could do is, as mentioned elsewhere, use diceSumTable = [] then diceSumTable.append((1,1)) for each dice combination.
You could also use a dictionary.
diceSumTable = {}
diceSumTable[2] = [(1,1)]
diceSumTable[3] = [(1,2),(2,1)]
#etc
You could then access by value rather than position.
>>>diceSumValue[3]
[(1,2),(2,1)]
>>>
You should index the list by it's indices, not the values:
In [123]: lst = [3, 4, 5]
In [124]: lst[0] == 3 #item "3" is at index 0
Out[124]: True
In [125]: lst[3] #out of range
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-125-48d1ca706e8c> in <module>()
----> 1 lst[3] #out of range
IndexError: list index out of range
In [126]: lst[1] = 10 #if I want to change "4" in the list to "10"
In [127]: lst
Out[127]: [3, 10, 5]
I am not shure of what result do you except from this code, what i understood is that you want to code to print :
[(1, 1)]
[(1, 2), (2, 1)]
[(1, 3), (2, 2), (3, 1)]
[(1, 4), (2, 3), (3, 2), (4, 1)]
[(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
[(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1)]
[(2, 6), (3, 5), (4, 4), (5, 3), (6, 2)]
[(3, 6), (4, 5), (5, 4), (6, 3)]
[(4, 6), (5, 5), (6, 4)]
[(5, 6), (6, 5)]
[(6, 6)]
In this case, i think the error you are making is believing that the following line :
diceSumTable = [2,3,4,5,6,7,8,9,10,11,12,13,14]
Give you a list where index start from 2 and finish at 14, which is wrong because in Python every list index start at 0, and there is no way you can change that. The line you give me, actually create a list where the first index is 0 and the last index is 12 (size of the list - 1). And you list is such that diceSumTable[0] is 2 diceSumTable[1] is 3, etc.
This lead you to two options, either accept that list start at index 0, and if you want to keep using the mapping you want (i guess there is a reason for that, you surely want to associate 2 with (1,1), 3 with (1,2), (2,1)) just use diceSumTable[theNumberOfYourMapping -2]. Or as say haavee, you can use dict for that. But in this case, when you will iterate over your dict, you won't have you value is the write order. If there is no gap between you're wanted index i will go with the map.
I think it will be great if you could explain use a bit more what you want to do, why do you want 2 and not 0 to be associated to [(1,1)]. Do you want to do something else with this lis t than printing it. To sum up here is the code, i would have written, if i understood what you wanted to do :
def dice():
diceSumTable = [[(1,1)],
[(1,2),(2,1)],
[(1,3),(2,2),(3,1)],
[(1,4),(2,3),(3,2),(4,1)],
[(1,5),(2,4),(3,3),(4,2),(5,1)],
[(1,6),(2,5),(3,4),(4,3),(5,2),(6,1)],
[(2,6),(3,5),(4,4),(5,3),(6,2)],
[(3,6),(4,5),(5,4),(6,3)],
[(4,6),(5,5),(6,4)],
[(5,6),(6,5)],
[(6,6)]]
#this is like for value in diceSumTable but i will iterate to 0,1..10 in more
for (i,value) in enumerate(diceSumTable):
print str(i+2) + " is associated to " + str(value)
dice()
Moreover if you want to know more about Python list, i could read :
http://effbot.org/zone/python-list.htm
And for Python dictionary :
http://www.pythonforbeginners.com/dictionary/dictionary-manipulation-in-pythonc

Categories