Python, Combining lists within a dict - python

Is it possible to combine lists in a dict to a new key?
For example, i have a dict setup
ListDict = {
'loopone': ['oneone', 'onetwo', 'onethree'],
'looptwo': ['twoone', 'twotwo', 'twothree'],
'loopthree': ['threeone', 'threetwo', 'threethree']}
I want a new key called 'loopfour' which contains the lists from 'loopone', 'looptwo', and 'loopthree'
So its list would look like
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']
and can be called using ListDict['four'] and return the combined list

Just use two for clauses in a list comprehension. Note however, dictionaries are not ordered so the resulting list can come out in a different order than they were originally put in the dictionary:
>>> ListDict['loopfour'] = [x for y in ListDict.values() for x in y]
>>> ListDict['loopfour']
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']
If you want it ordered then:
>>> ListDict['loopfour'] = [x for k in ['loopone', 'looptwo', 'loopthree'] for x in ListDict[k]]
>>> ListDict['loopfour']
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']

Related

How to compare two lists of dicts in Python and fetch difference

I am new to python. In Python, I want to compare two lists of dictionaries
Below are 2 list of dictionary I want to compare based on key which is "zrepcode" and id which is the number "1", "3", and "4"...
Code snippet is as follows:
List1 = [{"3":[{"period":"P13","value":10,"year":2022}],"zrepcode":"55"},{"1":[{"period":"P10","value":5,"year":2023}],"zrepcode":"55"}]
List2 = [{"1":[{"period":"P1","value":10,"year":2023},{"period":"P2","value":5,"year":2023}],"zrepcode":"55"},{"3":[{"period":"P1","value":4,"year":2023},{"period":"P2","value":7,"year":2023}],"zrepcode":"55"},{"4":[{"period":"P1","value":10,"year":2023}],"zrepcode":"55"}]
After Comparision, we need the unique list of dictionary from list2.
res = [{"4":[{"period":"P1","value":10,"year":2023}],"zrepcode":"55"}]
This is the expected output, Now I don't know how I get this.
You can use list comprehension to filter a list.
[x for x in list if condition]
and any() to see if a list has any elements matching a condition
any(condition for y in list)
or in your case, since you want those that don't exist in the other
[x for x in list2 if not any(your_condition for y in list1)]
To check if two elements have the same zrepcode value you can just compare them like
x['zrepcode'] == y['zrepcode']
Since your other point of comparison is a key and there are only two keys in each, you can compare the keys of both
x.keys() == y.keys()
Combine everything
[x for x in list2 if not any(x['zrepcode'] == y['zrepcode'] and x.keys() == y.keys() for y in list1)]

How can I make a one line generator expression to generate these two different lists

I am writing a program which parses lists like this.
['ecl:gry', 'pid:860033327', 'eyr:2020', 'hcl:#fffffd', 'byr:1937', 'iyr:2017', 'cid:147', 'hgt:183cm']
I want to turn this list into a dictionary of the key value pairs which I have done here:
keys = []
values = []
for string in data:
pair = string.split(':')
keys.append(pair[0])
values.append(pair[1])
zipped = zip(keys, values)
self.dic = dict(zipped)
print(self.dic)
I know that I can use list comprehension to make one of the lists at a time like this
keys = [s.split(':')[0] for s in data]
values = [s.split(':')[1] for s in data]
This requires two loops so the first code example would be better, but is there a way to generate both lists using one generator with unpacking and then zip the two together?
l = ['ecl:gry', 'pid:860033327', 'eyr:2020', 'hcl:#fffffd',
'byr:1937', 'iyr:2017', 'cid:147', 'hgt:183cm']
dict(e.split(':') for e in l)
I did it like this:
self.dic = {}
for e in data:
k, v = e.split(':')
self.dic[k] = v
You can dict comprehension it easily:
your_dict = {x.split(':')[0]: x.split(':')[1] for x in data}
You can also prevent from using split two times and use generator:
your_dict = dict(x.split(':') for x in data)
Which seems even cleaner...

Removing duplicates from a list of tuples in python

I have a list of tuples, and I want to remove duplicate tuples. Something like this.
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
I want the output something like this :
y = [['aaron','jeng'],['sdf','wqd']]
How can I do that in an easy way? I can write code to do that, but is there any inbuilt function for this?
Edit 1 : As everyone has suggested, I'm sorry to call them tuples. I meant a list of lists. Thank You.
Your x value does not contain a list of tuples, but a list of lists. If it did contain a list of tuples:
x = [('aaron','jeng'),('sdf','wqd'),('aaron','jeng')]
out = set([i for i in x])
print(list(out))
[('aaron', 'jeng'), ('sdf', 'wqd')]
That's a list of lists... But no matter, you can use a temporary set to make sure there are no repeats:
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
seen = set() # store here the visited tuples
y = [e for e in x if tuple(e) not in seen and not seen.add(tuple(e))]
# [['aaron', 'jeng'], ['sdf', 'wqd']]
If you convert your inner lists to tuples upfront it will have a considerably better performance.
If you don't need to preserve the order, then just convert the inner lists to tuples and turn your x to a set().
This would be easy with a list of tuples, you would simply need set(x). Since your list is a list of lists, and not a list of tuples, you can convert them first:
set(tuple(i) for i in x)
returns:
{('aaron', 'jeng'), ('sdf', 'wqd')}
Or, if you want to reconvert to a list of lists as you had it:
[list(t) for t in (set(tuple(i) for i in x))]
# [['aaron', 'jeng'], ['sdf', 'wqd']]
You can use enumerate and any:
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
new_x = [[a, b] for i, [a, b] in enumerate(x) if not any(c == b for _, c in x[:i])]
Output:
[['aaron', 'jeng'], ['sdf', 'wqd']]
You do not have tuples, you have lists inside lists.
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
uniques = list (set ( tuple(a) for a in x))
Is a generator expression fed into a set thats then fed to a list resulting in
[('aaron', 'jeng'), ('sdf', 'wqd')]
What about converting to a dict , Because dict can have unique keys :
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
print({tuple(i):i for i in x}.values())
output:
[['aaron', 'jeng'], ['sdf', 'wqd']]

Put average of nested list values into new list

I have the following list:
x = [(27.3703703703704, 2.5679012345679, 5.67901234567901,
6.97530864197531, 1.90123456790123, 0.740740740740741,
0.440136054421769, 0.867718446601942),
(25.2608695652174, 1.73913043478261, 6.07246376811594,
7.3768115942029, 1.57971014492754, 0.710144927536232,
0.4875, 0.710227272727273)]
I'm looking for a way to get the average of each of the lists nested within the main list, and create a new list of the averages. So in the case of the above list, the output would be something like:
[[26.315],[2.145],[5.87],etc...]
I would like to apply this formula regardless of the amount of lists nested within the main list.
I assume your list of tuples of one-element lists is looking for the sum of each unpacked element inside the tuple, and a list of those options. If that's not what you're looking for, this won't work.
result = [sum([sublst[0] for sublst in tup])/len(tup) for tup in x]
EDIT to match changed question
result = [sum(tup)/len(tup) for tup in x]
EDIT to match your even-further changed question
result = [[sum(tup)/len(tup)] for tup in x]
An easy way to acheive this is:
means = [] # Defines a new empty list
for sublist in x: # iterates over the tuples in your list
means.append([sum(sublist)/len(sublist)]) # Put the mean of the sublist in the means list
This will work no matter how many sublists are in your list.
I would advise you read a bit on list comprehensions:
https://docs.python.org/2/tutorial/datastructures.html
It looks like you're looking for the zip function:
[sum(l)/len(l) for l in zip(*x)]
zip combines a collection of tuples or lists pairwise, which looks like what you want for your averages. then you just use sum()/len() to compute the average of each pair.
*x notation means pass the list as though it were individual arguments, i.e. as if you called: zip(x[0], x[1], ..., x[len(x)-1])
r = [[sum(i)/len(i)] for i in x]

How to match and replace list elements in Python?

I have a list in Python with certain elements. I want to replace these elements with their corresponding elements from another list.
I want to have another list that relates elements in a list like:
x = ['red','orange','yellow','green','blue','purple','pink']
y = ['cherry','orange','banana','apple','blueberry','eggplant','grapefruit']
so that a new list will be created with the the corresponding elements from y whose elements are in x. So
r = ['green','red','purple']
will become
r = ['apple','cherry','eggplant']
Thanks
First create a mapping from one list to another:
my_mapping = dict(zip(x, y))
The zip part is mainly a formality: dict expects the argument to be a sequence of pairs, rather than a pair of sequences.
Then apply this mapping to every member of r using a list comprehension:
new_r = [my_mapping[elem] for elem in r]
Dictionaries are the best option for this. They are maps of key-value pairs so that if I index a dictionary with a key, it will return the value under that key.
Let's make a new dictionary using the zip function that takes two lists:
mapper = dict(zip(x,y))
Now, if we want to change a list r to its counterpart with elements from the new list:
r = [mapper[i] for i in r]
This takes each element in r and uses the dictionary to turn it into its counterpart.

Categories

Resources