Nesting dictionaries with a for loop - python-3.x

I am trying to add a dictionary within a dictionary in the current code like this!
i = 0
A ={}
x = [...]
for i in x:
(a,b) = func(x)#this returns two different Dictionaries as a and b
for key in a.keys():
A[key] = {}
A[key][i] = a[key]
print('A:',A)
as I executed it, I am getting 'A' dictionary being printed throughout the loop! But, i need them in one single dictionary say: "C"
How do I do that?

Related

Extracting lists from the lists of lists and assigning them into columns in python

I have a dataset(df_norm) with a column 'geometry.coordinates' that has a list of lists(l1) as it's value:
geometry.coordinates
0 [[[23.514690935490876, 53.946715071429367], [2...
1 [[[23.549827385369554, 53.942282407709513], [2...
2 [[[23.574999999999307, 53.941666666666151], [2...
I need to extract the individual coordinates from each list and assign each coordinate into a separate column, to get the output similar to this:
longitude1 latitude1 longitude2 latitude2 ...
23.514690935490876 53.946715071429367 23.5127605166679412 53.961345695020002
23.549827385369554 53.942282407709513 23.6123409888603434 53.941666666666151
....
The code I have is:
def flatten_list(l1):
flat_list = []
for sublist in df_norm['geometry.coordinates'][0]:
for item in sublist:
flat_list.append(item)
return flat_list
for i in range(len(df_norm['geometry.coordinates'])):
for j in df_norm['geometry.coordinates']:
flatten_list(df_norm['geometry.coordinates'])
var1 = flat_list[i][0]
var2 = flat_list[i][1]
var3 = flat_list[i][2]
var4 = flat_list[i][3]
var5 = flat_list[i][4]
I get an error:
IndexError: list index out of range
What am I doing wrong?
It seems your flatten_list() function produces a single un-nested list of all your values. However, when you index the list to assign the variables, you are using a nested notation flat_list[i][0].
In order to distribute the values from your new list produced by flatten_list() to the corresponding variables, try changing the indices as such:
for i in range(len(df_norm['geometry.coordinates'])):
for j in df_norm['geometry.coordinates']:
flatten_list(df_norm['geometry.coordinates'])
var1 = flat_list[i]
var2 = flat_list[i+1]
var3 = flat_list[i+2]
var4 = flat_list[i+3]
var5 = flat_list[i+4]
Further, if I understand your goal correctly, you want to produce lists under each of these variable names. As is, the loop will replace the values and only leave the final 5 values saved (one as each of the variables). Perhaps producing lists for each variable outside the loop and appending the values would be a better approach? Finally - a change to your range() parameters might be needed. Otherwise, duplicate values corresponding to one variable will be placed in the wrong variable as the temporary i variable progresses.
var1 = []
var2 = []
var3 = []
var4 = []
var5 = []
for i in range(0,len(df_norm['geometry.coordinates'],5)):
for j in df_norm['geometry.coordinates']:
flatten_list(df_norm['geometry.coordinates'])
var1.append(flat_list[i])
var2.append(flat_list[i+1])
var3.append(flat_list[i+2])
var4.append(flat_list[i+3])
var5.append(flat_list[i+4])
You got the error could be probably because you don't assign the value returned by the function.

Convert elements in ONE list to keys and values in a dictionary

I'm looking for a way to convert a list to a dictionary as shown below. Is this possible? Thanks in advance.
list = ["1/a", "2/b", "3/c"]
dict = {"1": "a", "2": "b", "3": "c"}
Of course it is possible.
First, you can split an element of the list with e.split("/"), which will give a list for example splitted = ["1", "a"].
You can assign the first element to the key and the second to the value:
k = splitted[0]
v = splitted[1]
or another way to express that:
k,v = splitted
Then you can iterate over your list to build your dict, so if we wrap this up (you should not call a list list because list is a type and an already existing identifier:
d = {}
for e in elements:
k,v = e.split("/")
d[k] = v
You can also do that in one line with a dict comprehension:
d = {k:v for k,v in [e.split("/") for e in elements]}
Yes you can.
If you want to have everything after the '/' (i.e. 2nd char), you can do:
dict = {c[0]:c[2:] for c in list}
If you want to have everything after the '/' (but may not be the 2nd char), you can do:
dict = {c[0]:c.split('/')[1] for c in list}
It really dependes on the input you have and what output you want
You can do like this.
lista = ["1/a", "2/b", "3/c"]
new_dict = {}
for val in lista:
new_dict.update({val[0]:val[2]})
print(new_dict)
Try this
list = ["1as/aasc", "2sa/bef", "3edc/cadeef"]
dict = {i.split('/')[0]:i.split('/')[1] for i in list}
Answer will be
{'1as': 'aasc', '2sa': 'bef', '3edc': 'cadeef'}
I have given a different test case. Hope this will answer your question.

Python losing track of index location in for loop when my list has duplicate values

I'm trying to iterate over pairs of integers in a list. I'd like to return pairs where the sum equals some variable value.
This seems to be working just fine when the list of integers doesn't have repeat numbers. However, once I add repeat numbers to the list the loop seems to be getting confused about where it is. I'm guessing this based on my statements:
print(list.index(item))
print(list.index(item2))
Here is my code:
working_list = [1,2,3,4,5]
broken_list = [1,3,3,4,5]
def find_pairs(list, k):
pairs_list = []
for item in list:
for item2 in list:
print(list.index(item))
print(list.index(item2))
if list.index(item) < list.index(item2):
sum = item + item2;
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
### First parameter is the name is the list to check.
### Second parameter is the integer you're looking for each pair to sum to.
find_pairs(broken_list, 6)
working_list is fine. When I run broken_list looking for pairs which sum to 6, I'm getting back (1,5) but I should also get back (3,3) and I'm not.
You are trying to use list.index(item) < list.index(item2) to ensure that you do not double count the pairs. However, broken_list.index(3) returns 1 for both the first and second 3 in the list. I.e. the return value is not the actual index you want (unless the list only contains unique elements, like working_list). To get the actual index, use enumerate. The simplest implementation would be
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for j, item2 in enumerate(list):
if i < j:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
For small lists this is fine, but we could be more efficient by only looping over the elements we want using slicing, hence eliminating the if statement:
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for item2 in list[i+1:]:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
Note on variable names
Finally, I have to comment on your choice of variable names: list and sum are already defined by Python, and so it's bad style to use these as variable names. Furthermore, 'items' are commonly used to refer to a key-value pair of objects, and so I would refrain from using this name for a single value as well (I guess something like 'element' is more suitable).

python3 value returned wrong with container variable

I meet a code that failed to meet my expectation. Details as below:
a = ['name']
b = [('name=cheng',),('name=huang',),('name=pan',)]
Dict = {}
c = []
for i in range(0,3):
for j in range(0,1):
Dict[a[j]] = b[i][j]
c.append(Dict)
print(c)
>>> [{'name':'name=pan'},{'name':'name=pan'},{'name':'name=pan'}]
what i expected should be
>>> [{'name':'name=cheng'},{'name':'name=huang'},{'name':'name=pan'}]
So could you please tell me how to solve the issue ?
You are changing the value of Dict in place and not creating a new dictionary every time. Each iteration of the loop, you are setting Dict["name"] equal to one of the elements in b and then appending it to the list. The next iteration of your loop changes dict in place (meaning the previous version you appending to c will also be changed). The result is that your list c is filled with 3 exact copies (exact same location in memory) of the dictionary created in the final iteration of the loop.
How do you fix this? Make a new dictionary every time.
a = ['name']
b = [('name=cheng',),('name=huang',),('name=pan',)]
c = []
for i in range(0,3):
for j in range(0,1):
temp_dict = {a[j]: b[i][j]}
c.append(temp_dict)
print(c)
Result:
[{'name': 'name=cheng'}, {'name': 'name=huang'}, {'name': 'name=pan'}]
You use the same value of Dict for all of the iterations of the loop. So all of the dictionaries are the same. You just have three copies of the same dictionary in the list.
If you move the Dict = {} statement into the loop, it will be fixed.
a = ['name']
b = [('name=cheng',),('name=huang',),('name=pan',)]
c = []
for i in range(0,3):
Dict = {}
for j in range(0,1):
Dict[a[j]] = b[i][j]
c.append(Dict)
print(c)
Or more Pythonic:
keys = ['name']
values_list = [('name=cheng',), ('name=huang',), ('name=pan',)]
result = []
for values in values_list:
result.append(dict(zip(keys, values)))
print(result)
This works by using the zip builtin which does the same thing as [(x[i], y[i]) for i in range(min(len(x), len(y))] without needing to keep track of the indices or lengths.
The dict class can build a dictionary from a list of tuples, which is what this solution uses.

Python3 - Combine Dictionaries with existing key value pairs

So... I know we can combine 2 dictionaries from python 3.5 like so:
z = {**x,**y} # x,y are 2 similar dictionaries, with nested entries
But in this method, any conflicting key,value pairs in 'x' is replaced with the ones in 'y'.
I want the conflicting key,value pairs to contain largest data present in x or y.
For example:
x = {1:'small_data',2:{1:'random laaaarge data',2:'random small data'}}
y = {1:'laaaaaarge_data',2:{1:'random small data',2:'random laaaarge data'}}
Now
z = {**x,**y}
# DATA in z should be {1:'laaaaaarge_data',2:{1:'random laaaarge data',2:'random laaaarge data'}}
NOTE: It should work for any arbitrary data that has a size.
Is this even possible? If so, what is the most pythonic way to do it.
Why not something like:
def merge_dicts(dict_list):
merged = {}
for sub_dict in dict_list:
for key, value in sub_dict.items():
if key in merged:
merged[key] = get_biggest(merged[key], value)
else:
merged[key] = value
return merged
def get_biggest(*items):
# function for comparing your 2 items based on your "size" requirements
return biggest

Resources