Not getting the right combination using itertools - python-3.x

I am trying to use itertools to get combination but i am not getting the combinations in the format that i want.
import itertools
dict = {(1,):1, (2,):3, (3,):1}
combo = list(itertools.combinations(dict.keys(),2))
print(combo)
Output:
[(('1',), ('2',)), (('1',), ('3',)), (('2',), ('3',))]
Output I want:
[('1','2',), ('1','3',),('2','3',)]

The output is expected as your dict keys are tuples. You may try the following:
>>> combo = list(itertools.combinations((key[0] for key in dict.keys()), 2))
>>> print(combo)
[(1, 2), (1, 3), (2, 3)]
This will extract the first ([0]) element from each dict key.

Related

Python how can create a subset from a integer array list based on a range?

I am looking around a way to get the subset from an integer array based on certain range
For example
Input
array1=[3,5,4,12,34,54]
#Now getting subset for every 3 element
Output
subset= [(3,5,4), (12,34,54)]
I know it could be simple, but didn't find the right way to get this output
Appreciated for the help
Thanks
Consider using a list comprehension:
>>> array1 = [3, 5, 4, 12, 34, 54]
>>> subset = [tuple(array1[i:i+3]) for i in range(0, len(array1), 3)]
>>> subset
[(3, 5, 4), (12, 34, 54)]
Links to other relevant documentation:
tuples
ranges
arr = [1,2,3,4,5,6]
sets = [tuple(arr[i:i+3]) for i in range(0, len(arr), 3)]
print(sets)
We are taking a range of values from the array that we make into a tuple. The range is determined by the for loop which iterates at a step of three so that a tuple only is create after every 3 items.
you can use code:
from itertools import zip_longest
input_list = [3,5,4,12,34,54]
iterables = [iter(input_list)] * 3
slices = zip_longest(*iterables, fillvalue=None)
output_list =[]
for slice in slices:
my_list = [slice]
# print(my_list)
output_list = output_list + my_list
print(output_list)
You could use the zip_longest function from itertools
https://docs.python.org/3.0/library/itertools.html#itertools.zip_longest

Python: How to use one dictionary to use to decode the other?

Say if I had two dictionaries:
d1 = {'a':1, 'b':2}
d2 = {'a':'b', 'b':'b', 'a':'a'}
How can I use dictionary d1 as the rules to decode d2, such as:
def decode(dict_rules, dict_script):
//do something
return dict_result
decode(d1,d2)
>> {1:2, 2:2, 1:1}
of course it can be written much shorter, but here a version to see the principle:
result_list = list()
result_dict = dict()
for d2_key in d2.keys():
d2_key_decoded = d1[d2_key]
d2_value = d2[d2_key]
d2_value_decoded = d1[d2_value]
result_dict[d2_key_decoded] = d2_value_decoded
# add a tuple to the result list
result_list.append((d2_key_decoded, d2_value_decoded))
the result might be unexpected - because the resulting dict would have entries with the same key, what is not possible, so the key 1 is overwritten:
>>> # equals to :
>>> result_dict[1] = 2
>>> result_dict[2] = 2
>>> result_dict[1] = 1
>>> # Result : {1:1, 2:2}
>>> # therefore I added a list of Tuples as result :
>>> # [(1, 2), (2, 2), (1, 1)]
but as #Patrik Artner pointed out, that is not possible, because already the input dictionary can not have duplicate keys !

python return list of sorted dictionary keys

I'm sure this has been asked and answered, but I cant find it. I have this dictionary:
{'22775': 15.9,
'22778': 29.2,
'22776': 20.25,
'22773': 9.65,
'22777': 22.9,
'22774': 12.45}
a string and a float.
I want to list the key strings in a tk listbox to allow the user to select one and then use the corresponding float in a calculation to determine a delay factor in an event.
I have this code:
def dic_entry(line):
#Create key:value pairs from string
key, sep, value = line.strip().partition(":")
return key, float(value)
with open(filename1) as f_obj:
s = dict(dic_entry(line) for line in f_obj)
print (s) #for testing only
s_ord = sorted(s.items(),key=lambda x: x[1])
print (s_ord)
The first print gets me
{'22775': 15.9,
'22778': 29.2,
'22776': 20.25,
'22773': 9.65,
'22777': 22.9,
'22774': 12.45}
as expected. The second, which I hoped would give me an ordered list of keys gets me
[('22773', 9.65),
('22774', 12.45),
('22775', 15.9),
('22776', 20.25),
('22777', 22.9),
('22778', 29.2)].
I have tried using sorteddictionary from the collections module and it gives me a sorted dictionary, but I'm having trouble extracting a list of keys.
s_ord2 = []
for keys in s.items():
s_ord2.append (keys)
print (s_ord2)
gives me a list of key value pairs:
[('22776', 20.25),
('22777', 22.9),
('22774', 12.45),
('22773', 9.65),
('22778', 29.2),
('22775', 15.9)]
I'm sure I'm doing something dumb, I just don't know what it is.
You're using items when you want to use keys:
In [1]: d = {'z': 3, 'b': 4, 'a': 9}
In [2]: sorted(d.keys())
Out[2]: ['a', 'b', 'z']
In [3]: sorted(d.items())
Out[3]: [('a', 9), ('b', 4), ('z', 3)]
d.items() gives you tuples of (key, value); d.keys() just gives you just the keys.

PySpark cogroup on multiple keys

Given two lists, I want to group them based on the co-occurence of the first two keys:
x=[(1,(2,'cat')),(4,(5,'dog'))]
y=[(1,(2,'hairBall')),(4,(5,'woof'))]
desired output:
z=[(1,2,('cat','hairBall')),(4,5,('dog','woof'))]
what I have tried so far:
sc=SparkContext()
xs=sc.parallelize(x)
ys=sc.parallelize(y)
zs_temp=xs.cogroup(ys)
this results in:
zs_temp.collect()=[(1, [[(2, 'cat')], [(2, 'hairBall')]]), (4, [[(5, 'dog')], [(5, 'woof')]])]
attempted solution:
zs_temp.map(lambda f: f[1].cogroup(f[1]) ).collect()
but get the error:
AttributeError: 'tuple' object has no attribute 'cogroup'
Test Data:
x=[(1,(2,'cat')),(4,(5,'dog'))]
y=[(1,(2,'hairBall')),(4,(5,'woof'))]
xs=sc.parallelize(x)
ys=sc.parallelize(y)
Function to change the keys
def reKey(r):
return ((r[0], r[1][0]), r[1][1])
Change keys
xs2 = xs.map(reKey)
ys2 = ys.map(reKey)
Join Data, collect results
results = ys2.join(xs2)
results.collect()
[((1, 2), ('hairBall', 'cat')), ((4, 5), ('woof', 'dog'))]

How to add a pair to a dictionary in python?

I created the following dictionary: d = {}
I add to it a new key and a couple as the corresponding d['Key1'] = (1, 2)
If I print the dictionary
{ 'Key1': (1, 2) }
How can I add another pair of integers to the following dictionary to the following key in order to have
{ 'Key1': (1, 2), (1, 3), (1, 4)}
Is it possible to do it in Python? if yes How can I do it?
Can I also count the number of values that correspond to a specific key?
Yes its possible but you need to use a container for your values.
For example you can use a list,also you can use dict.setdefault method for assignment if your keys will have a multiple values, this is useful of you want to add another key with multiple values :
>>> d = {}
>>> d.setdefault('Key1',[]).append((1,2))
>>> d
{'Key1': [(1, 2)]}
>>> d['Key1'].append((1, 3))
>>> d
{'Key1': [(1, 2), (1, 3)]}
>>> d.setdefault('Key2',[]).append((4,2))
>>> d
{'Key2': [(4, 2)], 'Key1': [(1, 2), (1, 3)]}
setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
That's only possible if you make the initial entry a list.
D['key'] = []
D['key'].append((1,2))
D['key'].append((3,4))
{'Key': [(1,2), (3,4)] }
You can't do it directly; in other words, a dict can't hold multiple values associated with the same key. You would need to have a dict of lists.
If the set of keys isn't known in advance, you might want to use a defaultdict, which will automatically create a list (or whatever) each time you access a key which doesn't already exist in the dictionary.
d = collections.defaultdict(list)
To add elements, you would use
d['Key1'].append((1, 2))
instead of
d['Key1'] = (1, 2)
This lets you avoid writing special code to handle the first insertion with a given key.

Resources