Combining two multi-dimensional arrays [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Having this two arrays in Python:
a = [ ['a',1], ['b',2], ['c',3] ]
b = [ ['a',10], ['b',20], ['c',30], ['d',40] ]
Is it possible to combine them into a single array like this?
output = [ ['a',1,10], ['b',2,20], ['b',3,30], ['c',0,40] ]
Since 'c' doesn't exist in the first array, first integer should be 0.
Thank you.

As stated in the comments, if missing values can be at any place, you cannot use zip or zip_longest. Here I use dicts for joining values:
a = [ ['a',1], ['b',2], ['c',3] ]
b = [ ['a',10], ['b',20], ['c',30], ['d',40] ]
d1, d2 = dict(a), dict(b)
d = {k: [d1.get(k, 0), d2.get(k, 0)] for k in d1.keys() | d2.keys()}
print( sorted([k, *v] for k, v in d.items()) ) # use custom key= to sort them to right order (or don't use sort if you don't need it)
Prints:
[['a', 1, 10], ['b', 2, 20], ['c', 3, 30], ['d', 0, 40]]

It would seem to me that picking a dictionary for your datatype would make more sense than lists, but if you need to use lists, this is an approach:
the lists in the original lists, are really just tuples, matching key to value; a dictionary would make more sense here
you want one list in the result for each key in the original lists
the lists in the result list, are really just 3-tuples, matching key to first and second value
you want the value from the first list for each key (or 0 if none) as the first value
you want the value from the first list for each key (or 0 if none) as the second value
da = {l[0]: l[1] for l in a}
db = {l[0]: l[1] for l in b}
result = [
[k, da[k] if k in da else 0, db[k] if k in db else 0]
for k in sorted(set(list(da.keys()) + list(db.keys())))
]
print(result)
Note that the sorted() is in there to preserve order. If alphabetical order isn't guaranteed, you can just combine the keys and dedupe using something like this:
def dedupe(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]

Related

How to loop between a list and dictionary to get frequencies in separate list (Python) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to loop between a list full of characters to iterate and match up with the values in the dictionary to ultimately grab frequencies set on another list. For example:
a = ['NIEP','LOAS','IJFE','NIEP'] #list of characters
b = [] #empty list that would ultimately contain all the matching values
di = {'NIEP':0,'IJFE':0} #dictionary values with frequency counts set to 0
What b would ideally look like:
b = ['NIEP':2,'IJFE':1] #the numbers are the amount of times they repeat in list a
I have tried:
b = []
for x in di.keys():
if x in a:
b.append(di[x])
This returns an empty list and 0 values like [0,0]. I also tried:
b = [di[x] for x in a if x in di]
Which is the same thing but in a different format, it still returns the zeros just 3 of them.
Your b should be a dictionary because you're hunting the frequency of a matching reference with di dictionary. First iterate the list a then count if it exist in the dictionary di.
a = ['NIEP','LOAS','IJFE','NIEP'] #list of characters
di = {'NIEP':0,'IJFE':0}
b = {}
for x in a:
if x in di.keys():
if x in b:
b[x]+= 1
else:
b[x]=1
print(b)
OUTPUT
{'NIEP': 2, 'IJFE': 1}
Since you are starting with a dictionary containing keys and zero values, it seems like you want to maintain these zero values for keys even if they are not in a. One way to do that is to take a count of the values in a if the key is in di and then merge them with the original di. For example:
from collections import Counter
a = ['NIEP','LOAS','IJFE','NIEP'] #list of characters
di = {'NIEP':0,'IJFE':0}
b = {**di, **Counter(s for s in a if s in di)}
# {'NIEP': 2, 'IJFE': 1}
If di has additional keys, those will be preserved with the 0 value:
a = ['NIEP','LOAS','IJFE','NIEP'] #list of characters
di = {'NIEP':0,'IJFE':0, 'NULL': 0}
b = {**di, **Counter(s for s in a if s in di)}
# {'NIEP': 2, 'IJFE': 1, 'NULL': 0}
A further alternative, if you want to keep the counter rather than a dict is to make the counter, then update it to get the zero values:
b = Counter(s for s in a if s in di)
b.update(di)
# b will be Counter({'NIEP': 2, 'IJFE': 1, 'NULL': 0})
Just use the builtin functionality collections.Counter
from collections import Counter
a = ['NIEP','LOAS','IJFE','NIEP']
di = {'NIEP':0,'IJFE':0}
b = Counter(value for value in a if value in di)
print(b)
Output
Counter({'NIEP': 2, 'IJFE': 1})
But if you want a list of results
...
b = [{key: value} for key, value in b.items()]
print(b)
Output
[{'NIEP': 2}, {'IJFE': 1}]
You can use Counter from Collections -
from collections import Counter
a = ['NIEP','LOAS','IJFE','NIEP']
b = dict(Counter(a))
print(b)
Result:
a = ['NIEP','LOAS','IJFE','NIEP']
Or, if you do not want to use a module then try -
b = {ele:a.count(ele) for ele in a} # A dict Comprehension
{'NIEP': 2, 'LOAS': 1, 'IJFE': 1}
Or try:
>>> a = ['NIEP','LOAS','IJFE','NIEP']
>>> {k: a.count(k) for k in a}
{'NIEP': 2, 'LOAS': 1, 'IJFE': 1}
>>>

Transform multiple lists to dictionary of tuples [duplicate]

This question already has answers here:
How to map multiple lists to one dictionary?
(2 answers)
Closed 2 years ago.
I'm attempting to convert multiple lists into a dictionary where the initial list contains the keys.
For example:
list_keys = ['a' , 'b']
list_vals_1 = ['tick' , 'tack']
list_vals_2 = ['big' , 'small']
is transformed into:
expected = {}
expected['a'] = ('tick' , 'big')
expected['b'] = ('tack', 'small')
print('expected' , expected)
I could transform the lists using into a dictionary using:
mappings = {}
i = 0
for l in list_keys :
mappings[l] = (list_vals_1[i] , list_vals_2[i])
i = i + 1
Is there a cleaner/better solution using Python to accomplish this ?
try zip
dict(zip(list_keys, zip(list_vals_1, list_vals_2)))
{'a': ('tick', 'big'), 'b': ('tack', 'small')}
Use zip():
>>> {k: (v1, v2) for k, v1, v2 in zip(list_keys, list_vals_1, list_vals_2)}
{'a': ('tick', 'big'), 'b': ('tack', 'small')}
Also, for what it's worth, you could have used enumerate() to improve your existing solution:
for i, k in enumerate(list_keys):
mappings[k] = (list_vals_1[i], list_vals_2[i])
By the way, note that l is a bad variable name since it looks like 1 and I. I used k instead - short for "key".

Python group and sum with string as keys [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Beginners question...
If possible without pandas, I'd like to sum up groups within a list or an array.
Input:
Input = [["A",0.2],["B",0.5],["A",0.6],["C",0.1],["B",0.9]]
Desired Output:
Output = [["A",0.8],["B",1.4],["C",0.1]]
Thanks!
You could sum over equal keys by using a dictionary. If you really need, you still can recreate the result to a list of lists via a list comprehension:
lst = [["A",0.2],["B",0.5],["A",0.6],["C",0.1],["B",0.9]]
d = dict()
for sl in lst:
d[sl[0]] = d.get(sl[0], 0) + sl[1]
res = [[k, v] for k, v in d.items()]
You can by doing this:
from collections import defaultdict
sums = defaultdict(lambda: 0)
for arr in input:
sums[arr[0]] += arr[1]
output = [[key, value] for key,value in sums.items()]
This way seems the most idiomatic for me. Following the convention of Python, you should name your variables with lower case and underscore. You can learn more about the defaultdict here: https://docs.python.org/3.6/library/collections.html
You can use this :
Dict = {group[0]: 0 for group in Input}
for group in Input: Dict[group[0]] += group[1]
Output = [[group, value] for group, value in Dict.items()]
A dict can only have unique keys, so we solve half of the problems. To start, each value of each key will be 0.
Next, we iterate through Input and add each value to its corresponding key in our Dict. So now, our job is almost done.
We only have to convert it to the form you want, using a comprehension list.
I would recommend going for a dict as shown hereunder:
inp = [["A",0.2],["B",0.5],["A",0.6],["C",0.1],["B",0.9]]
#create an empty dict
out = {}
#for each element of the inp list
for a in inp:
#if the key does already exist in the dict, you sum the current value
#with what was found in the array at this iteration
if a[0] in out:
out.update({a[0]:a[1]+out.get(a[0])})
#you create a new pair (new key, new value) extract from inp
else:
out.update({a[0]:a[1]})
print out
#if you really need a nested list as output you can convert back the dict
#into a list of list
res = [[key, val] for key, val in out.items()]
print res
output:
{'A': 0.8, 'C': 0.1, 'B': 1.4}
[['A', 0.8], ['C', 0.1], ['B', 1.4]]
This should work:
Output = [ [k,sum(a[1] for a in Input if a[0] == k)] for k in set(a[0] for a in Input) ]

Get the name of the dictionary that contains the given key in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
a = {'name1':'tom'}
b = {'name2':'harry'}
c = {'name3':'peter'}
For a given key, I would like to get the name of the dictionary contains it.
Example:
If i give 'name2', I would like to get b as the result
Thanks
You can use next to return the next value in a sequence, and filter it based on some criteria:
key = 'name2'
found = next(d for d in (a, b, c)
if key in d)
a = {'name1':'tom'}
b = {'name2':'harry'}
c = {'name3':'peter'}
name = 'name2'
for k, v in locals().copy().items():
if isinstance(v, dict):
if name in v:
print('"{}" contains id dict "{}"'.format(name, k))
# "name2" contains in dict "b"
But usually you shouldn't do it. Create dict of dicts and iterate through it:
ds = {
'a': {'name1':'tom'},
'b': {'name2':'harry'},
'c': {'name3':'peter'},
}
name = 'name2'
for k, v in ds.items():
if name in v:
print('"{}" contains id dict "{}"'.format(name, k))
# "name2" contains in dict "b"
Let's say that you put references to your dictionaries in an iterable
l = [da, db, dc, ...]
that you initialize the reference to one of your dictionaries to an invalid value
d = None
to find which dictionary has word as a key it's simply
for _ in l:
if word in _:
d = _
break
at this point, either you didn't find word in any of your dicts and d is hence still equal to None, or you've found the dictionary containing word
and you can do everything you want to it
if d:
...
Since you said you would like to get b back as a variable, one way I can think of doing this is making a list of your dictionaries and enumerating through them.
a = {'name1':'tom'}
b = {'name2':'harry'}
c = {'name3':'peter'}
name = 'name2'
dicts = list(a,b,c)
required_dic = findDict(dicts)
def findDict(dicts):
for obj in dicts:
if "name2" in obj:
return obj
but as #germn said, a better idea would be to create a nested dictionary.
You may create a mapping dict, which maps the key to variable binding:
{"name1" : a, "name2" : b, "name3" : c}

Combining two list to make a dictionary [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I need to convert two list into a dictionary. I have two list named A and B,
A = [[1,2,3] [2,3,4] [1,4,5] [1,3,4]]
the values in A (list of list) will be unique
B = [[10,13,23] [22,21,12] [5,34,23] [10,9,8]]
the length of both list will be same
I need the result like
C = [['1' :10 , '2' :13, '3': 23] ['2':22, '3':21, '4':12] ['1':5, '4':34, '5':23] ['1':10, '3':9, '4':8]]
I tried the dict method but it is throwing me an error saying list is un hashable type. Please let me know how to do this. Im new to python.
It's hard to be sure, but I'm guessing your problem is this:
If a and b were just flat lists of numbers, all you'd have to do is this:
dict(zip(a, b))
And I'm assuming that's similar to what you wrote. But that doesn't work here. Those aren't lists of numbers, they're list of lists. And you don't to get back a dict, you want a list of dicts.
So, you're asking Python to create a dict whose keys are the sub-lists of a, and whose values are the sub-lists of b. That's an error because lists can't be keys, but it wouldn't be useful even if that weren't an issue.
To actually do this, you need to not only zip up a and b, but also zip up their sublists, and pass those sub-zips, not the main zip, to dict. Like this:
[dict(zip(suba, subb)) for (suba, subb) in zip(a, b)]
I think you want C to be a list of dictionaries. Here's a straightforward way to do that.
def combine(keys, values):
"generate a dictionary from keys and values"
out = {}
for k,v in zip(keys,values):
out[k] = v
return out
def combine_each(keys, values):
"for each pair of keys and values, make a dictionary"
return [combine(klist, vlist) for (klist,vlist) in zip(keys,values)]
C = combine_each(A,B)
Alternative:
>>> A = [[1,2,3], [2,3,4], [1,4,5], [1,3,4]]
>>> B = [[10,13,23], [22,21,12], [5,34,23], [10,9,8]]
>>> [{k:v for k, v in zip(sa, sb)} for (sa, sb) in zip(A, B)]
[{1: 10, 2: 13, 3: 23}, {2: 22, 3: 21, 4: 12}, {1: 5, 4: 34, 5: 23}, {1: 10, 3: 9, 4: 8}]

Categories