b = [['a', '1'], ['b', '2'], ['c', '3']]
c = {}
for i in range(len(b)):
m = i[0]
c[m] = i[1]
My goal is to make the nested list b into a dictionary. However, I keep getting an error saying
TypeError: 'int' object is not subscriptable
Try this:
b = [['a', '1'], ['b', '2'], ['c', '3']]
d={}
for i in b:
d[i[0]]=i[1]
I'll explain the main issue with your code. But bottom line, best to use a dict comprehension:
{k:v for k, v in b}
# {'a': '1', 'b': '2', 'c': '3'}
Or just:
dict(b)
Your code as is will throw an error:
TypeError: 'int' object is not subscriptable
To understand why, try for i in range(len(b)): print(i). You'll see that your loop iteration values are just the index values of b, not the lists stored in b.
So doing i[0] won't work, since i is just an integer. What you want is more like b[i][0]. But there are easier ways to do that.
In particular, try instead: for i in b: print(i).
You'll see that now your iterations are putting each list inside b into i, and then you can do m = i[0] as planned. After that, your code will work, storing each dict value (i[1]) in each dict key (m):
for i in b:
m = i[0]
c[m] = i[1]
Note: While it is convention to use i when keeping track of index values, it's not really best practice (for that same reason) to use i for other kinds of iteration values. To avoid confusing your future self, use x or even current_list instead of i as your loop iterator name in situations like this. (But really, I'd advise just using the simpler alternatives I started out with at the top of this post.)
The issue is you are attempting to index into an integer i as if it was a list. I think you meant b[i][0] (this says: give me the 0-th item of the i-th item in b).
This is a little easier:
b = [['a', '1'], ['b', '2'], ['c', '3']]
d = dict(b)
print(d)
Output:
{'a': '1', 'b': '2', 'c': '3'}
Related
Given a list like list1 = [[1,2,3],[4,5,6]], in order to get back [['1','2','3'],['4','5,'6']], I have tried this:
for i in list1:
for j in i:
j = str(j)
list1
which does nothing to the list: it outputs list1 unchanged. I though it would work by reassigning, something like a[0][0] = str(a[0][0]) (which does work) in a loop. Of course, the for loop above won't do that.
Also tried "map", as in
for i in list1:
for j in i:
list(map(str,i)
which also doesn absolutely nothing to list1.
I am trying to alter the original list, which should be possible. Maybe a new list would be the case, but I'm almost sure it's unnecessary.
Can someone help?
Thank you.
You can try list comprehension
[[str(j) for j in i] for i in list1]
# or
# [list(map(str,i)) for i in list1]
[['1', '2', '3'], ['4', '5', '6']]
Use nested list comperhension
list1 = [[1,2,3],[4,5,6]]
[[str(x) for x in y] for y in list1]
will return
[['1', '2', '3'], ['4', '5', '6']]
Yes, you can use map function somehow like this:
def convert(x=[]):
return [str(i) for i in x]
>>list(map(convert,x))
[['1', '2', '3'], ['4', '5', '6']]
Please check out mutable/immutable objects in Python
for i in list1: # i is a list(mutable)
for j in i: # j is an int(immutable)
j = str(j) # j reference to new string object
int is immutable (not allow changes after creation), so this line
j = str(j)
created a new string object referred by j and the object in list i remains unchanged.
list, dict, set, byte array are mutable objects.
Changing the object value in a list can be done like this:
for i in list1: # i is a list(mutable)
for j in range(len(i)): # this time, j is index of list i
i[j] = str(i[j]) # change the list values
And the result,
list1
[['1', '2', '3'], ['4', '5', '6']]
I'm currently trying to wrap my head around list comprehensions and try to get some practice by taking examples and form loops out of comprehensions and vice versa. Probably a really easy mistake, or a forest for the trees situation. Take the following expression taken from an example project:
rows = []
data = ['a', 'b']
res = ['1', '2']
rows.append({data[counter]: res[counter] for counter, _ in enumerate(data)})
print(rows):
[{'a': '1', 'b': '2'}]
How do i do this as a for loop? The following wraps each loop into a curly bracket instead of both.
for counter, _ in enumerate(data):
rows.append({data[counter]: res[counter]})
print(rows):
[{'a': '1'}, {'b': '2'}]
Am i missing something? Or do i have to merge the items by hand when using a for loop?
The problem in your code is that you create a dictionary for each item in data and append it to rows in each iteration.
In order to achieve the desired behaviour, you should update the same dict in each iteration and after you finish working on your dictionary, only then you should append it to rows.
Try this:
rows = []
data = ['a', 'b']
res = ['1', '2']
payload = {}
for counter, val in enumerate(data):
payload[val] = res[counter]
rows.append(payload)
Another compact way to write it might be:
rows.append(dict(zip(data,res)))
On every iteration of for loop you are creating a new dictionary and appending it into a list if you want to store a whole dictionary in a list then You should try something like that it outputs as you expected:
rows = []
data = ['a', 'b']
res = ['1', '2']
myDict = {}
for counter, _ in enumerate(data):
myDict[data[counter]]= res[counter]
rows.append(myDict)
print(rows)
Output:
[{'b': '2', 'a': '1'}]
I have the following:
d1={"00f_125":["A","2","3"],
"00f_126":["1","2","3"],
"00f_127":["T","2","3"],
"00f_128":["T","2","3"]}
d2=[{"marker":"00f_125","1":"T"},
{"marker":"00f_126", "1":"G"},
{"marker":"00f_127","1":"T"}]
I would like to replace when there is only an integer present. This is the output I would like:
d3={"00f_125":["A","2","3"],
"00f_126":["G","2","3"],
"00f_127":["T","2","3"],
"00f_128":["T","2","3"]}
Is this possible? Any help would be appreciated.
This is one approach using a simple iteration
Ex:
d1={"00f_125":["A","2","3"],"00f_126":["1","2","3"],"00f_127":["T","2","3"],"00f_128":["T","2","3"]}
d2=[{"marker":"00f_125","1":"T"},{"marker":"00f_126", "1":"G"},{"marker":"00f_127","1":"T"}]
for i in d2:
if i["marker"] in d1:
if d1[i["marker"]][0] in i:
d1[i["marker"]][0] = i[d1[i["marker"]][0]]
Output:
{'00f_125': ['A', '2', '3'],
'00f_126': ['G', '2', '3'],
'00f_127': ['T', '2', '3'],
'00f_128': ['T', '2', '3']}
It's pretty simple to do in-place on d1:
for elem in d2:
marker = elem["marker"]
if "1" in d1[marker]: # is that specific int in d1?
i = d1[marker].index("1") # if so, then find its index
d1[marker][i] = elem["1"] # and replace it with your desired value
This is, of course, an oversimplification. If you have more than one key besides "marker", you might want to put all of those keys into a list within that dict (e.g.
d2=[{"marker": "00f_125", "modifications": ["1": "G", "2": ...]}, ...]
), which would make it easier to iterate through them without hardcoding the value like I did above.
If you wanted to produce a separate dict d3 without modifying the original, then you could make a shallow or deep copy of d1 before doing this.
d3 = d1.copy()
for i in d2:
key = i['marker']
if key in d3.keys():
if (d3[key][0].isdigit()):
d3[key][0] = i['1']
print(d3)
You can copy d1 to d3 and directly make changes in d3. For every list in d2, if the marker value is present in d3, then check if the first element is an integer. If it is, then replace that number with the character value.
This is the output of the above code.
d3 = {'00f_126': ['G', '2', '3'],
'00f_125': ['A', '2', '3'],
'00f_127': ['T', '2', '3'],
'00f_128': ['T', '2', '3']}
This is another generic approach without specifying the keys
for i in d2:
for key in i.keys():
if i.get(key) in d1:
lis_val = d1.get(i.get(key))
if key in lis_val:
lis_val[lis_val.index(key)] = i.get(key)
Output:
{
'00f_125': ['A','2','3'],
'00f_126': ['G','2','3'],
'00f_127': ['T','2','3'],
'00f_128': ['T','2','3']
}
I have a dictionary:
{'dict': [['IE', '5', '-5'], ['UK', '3', '-9']]}
I wish to pop the list values that are outside of the UK, therefore taking the first value within the lists and comparing to see if it is equal to 'UK'.
I currently have:
for k,v in insideUK.items():
for i in v:
if i[0] == "UK":
print(x)
else:
k.pop(v)
I know after the else is wrong but need help!
I wish for the dict to look like this once finished popping values that aren't equal to "UK".
{'dict': [['UK', '3', '-9']]}
You can use a list comprehension to filter out based on the first element
>>> data = {'dict': [['IE', '5', '-5'], ['UK', '3', '-9']]}
>>> {'dict': [i for i in data['dict'] if i[0] == 'UK']}
{'dict': [['UK', '3', '-9']]}
You can also do it using the filter function:
d = {'dict': list(filter(lambda i: 'UK' in i, d['dict']))}
print(d)
Output:
{'dict': [['UK', '3', '-9']]}
A nested dict and list expression can do this:
{k: [i for i in v if i[0] == 'UK'] for k,v in insideUK.items()}
If you really want to do it with a for-loop and change the list in-place, you could do something like this:
for k,v in insideUK.items():
for i in v:
if i[0] == "UK":
print(x)
else:
v.remove(i)
But it is discouraged strongly to change the list you are iterating over during the iteration
I would like to find the intersection of lists that are stored within the defaultdict(list) container. Here is my dictionary, 'd' a list of lookup values, 'my_list':
d = { a: ['1', '2', '3'],
b: ['3', '4', '5'],
c: ['3', '6', '7']
}
my_list = ['a', 'b']
I would like to return the intersection of the lists. Based on a previous post I tried the following but get an error: TypeError: unhashable type: 'list'
set.intersection(*map(set,d[my_list]))
any suggestions would be welcome.
thanks,
zach cp
The problem is that you are trying to access d[my_list] – a list is not a vlaid dictionary key. One alternative:
set.intersection(*(set(d[k]) for k in my_list))