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'}]
Related
for solving above problem I normally use for loop like that:
list1 = ['1', '2', 3,32423,5.76, "afef"]
list2 = []
for ele in list1:
list2.append(str(ele))
does python has some build in function for solving that problem?
You can use the built-in function map like the following:
list1 = ['1', '2', 3, 32423, 5.76, "afef"]
list2 = list(map(str, list1))
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']
}
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'}
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'm trying to match a list of items to another list of items of a different dimension and print an element from the second list if the item is matched. For example:
stlist=['6', '3', '4', '2', '5', '1']
ndlist=[['Tom', '1'], ['Joh', '2'], ['Sam', '3'], ['Tommy','4'], ['Nanni', '5'], ['Ron', '6']]
My outputlist is producing the names in the ascending order of my stlist.
i.e Tom, Joh, Sam, Tommy, Nanni, Ron but I want the outputlist to be in the same order as the stlist.
My Python code is:
for sublist in ndlist:
for element in stlist:
if element in sublist[1]:
print(sublist[0])
The outputlist displayed from the above codes is: Tom, Joh, Sam, Tommy, Nanni, Ron instead of
outputlist = [Ron, Sam, Tommy, Joh, Nanni, Tom]
So it's actually sorting in ascending order my 1stlist and printing the names from the 2ndlist in that order.But if my stlist was in ascending order the outputlist would be fine.
Can anyone tell me why please and how should I modify the codes to get my desired outputlist.
Try to rearrange your for loops:
for element in stlist:
for sublist in ndlist:
if element in sublist[1]:
print (sublist[0])
Also, the if statement should maybe be like this: if element == sublist[1]: or else the element '1' would be found in some ndlist element like this one: ['foo', '10']
Furthermore, this solution is not the most efficient with large lists. To make it more efficient you could try something like sorting the ndlist and performing binary search to check if an element exists.
You could use sorted and a custom sort key (a Lambda function) to do this:
>>> [i[0] for i in sorted(ndlist, key = lambda x:stlist.index(x[1]))]
['Ron', 'Sam', 'Tommy', 'Joh', 'Nanni', 'Tom']
This line of code sorts ndlist using the position of the numbers in stlist as the sort key, then a list comprehension builds a new list containing only the names.
Instead of nesting loops or sorting you could also create a mapping with one linear run through ndlist and then use another linear run through stlist to build the result list:
mapping = dict((b, a) for a, b in ndlist)
result = [mapping[x] for x in stlist]
print(result)