I am trying to create a complete graph in a Python Dictionary in 1 line. But when creating the list comprehension for the values I can not figure out how to specify that the key_value can not appear in the list of values (in graph speak, no self loop).
for n nodes
G = {k:[v for v in range(n)] for k in range(n) }
results in this (example n = 3)
{0: [0, 1, 2], 1: [0, 1, 2], 2: [0, 1, 2]}
but what I want is this
{0: [1, 2], 1: [0, 2], 2: [0, 1]}
But trying something similar to this
G = {k:[v for v in range(n) for v !=k] for k in range(n) }
will throw an error at the k in the list comprehension. So k must be out of scope for the list comprehension, which makes sense.
Can G be defined in this method?
To ignore the key's value from the value list, you just have to put a validation in your list comprehension.
G = { k: [v for v in range(n) if v != k] for k in range(n) }
So for n = 3 you graph G would return :-
{0: [1, 2], 1: [0, 2], 2: [0, 1]}
Related
my code is this
idnt=[]
idntfrq=[]
for i in range(len(occ)):
idnt.append([])
idntfrq.append([])
for j in range(len(occ[i])):
for j2 in range(j,len(occ[i])):
for d in occ[i][j]:
idnt[i].append(d)
idntfrq[i].append([j])
occ[i][j].remove(d)
for d2 in occ[i][j2]:
if d==d2:
idntfrq[i][-1].append(j2)
occ[i][j2].remove(d)
I need the number of appearances of each value as well as their indexes
the list of lists is occ (50 lists inside with various lengths each)
the thought was to iterate over everything,store each value in the idnt[i] list and the
index of the list in which it appears to the idntfrq[i] list and then remove the
element from the list of the current itteration,the occ list should be empty after
that but it is not,i uploaded a prntscr of the occ[0][0] to see what i mean
NOTE: each list inside a list contains every element only once , but i want to count the
occurences across all the lists inside every occ[i] (for i in 50)and also keep the indexenter image description here
This code will do what you are asking:
mainList = [[1,2,3],[3,4,5],[1,5,9]]
d = {}
for l in mainList:
for item in l:
if item in d.keys():
d[item] +=1
else:
d[item] = 1
print(d)
Output:
{1: 2, 2: 1, 3: 2, 4: 1, 5: 2, 9: 1}
It gives the answer in a dictionary where keys are the items and the values is the number of appearances.
This output and be further formatted if needed.
If you need the indexes of each time a number appears you can simply add a dictionary di that has the items as keys and a list of index pairs at which the item appears as the values.
This can be done by adding di[item].append([idx,jdx]) and di[item] = [[idx,jdx]] inside the loop and defining it as di = {} before the loop like this:
mainList = [[1,2,3],[3,4,5],[1,5,9]]
d = {}
di = {}
idx = -1
for l in mainList:
idx += 1
jdx = -1
for item in l:
jdx += 1
if item in d.keys():
d[item] +=1
di[item].append([idx,jdx])
else:
d[item] = 1
di[item] = [[idx,jdx]]
print(d)
print(di)
Ouput:
{1: 2, 2: 1, 3: 2, 4: 1, 5: 2, 9: 1}
{1: [[0, 0], [2, 0]], 2: [[0, 1]], 3: [[0, 2], [1, 0]], 4: [[1, 1]], 5: [[1, 2], [2, 1]], 9: [[2, 2]]}
I think this works:
from collections import Counter
list_of_lists = [[1, 2, 3], [4, 1, 2], [3, 4, 5]]
counter = Counter()
for _list in list_of_lists:
counter.update(_list)
I have two nested lists:
a = [[0, 1],[1, 0],[2, 0]]
b = [[2, 1],[1, 3],[8, 1]]
I want to have a list of dictionaries such that each inner element of list a (as key) corresponds to it's inner element of list b (as value).
Here's my desired output:
[{0:2,1:1},{1:1,0:3},{2:8,0:1}]
I've tried:
ls = []
for i in a:
for j in b:
ls.append({k:v for k,v in zip(i, j)})
print(ls)
But it gives me all the possible combinations which I don't want. Any help is appreciated.
You use a list comprehension and zip.
>>> a = [[0, 1],[1, 0],[2, 0]]
>>> b = [[2, 1],[1, 3],[8, 1]]
>>> [dict(zip(i, j)) for i, j in zip(a, b)]
[{0: 2, 1: 1}, {1: 1, 0: 3}, {2: 8, 0: 1}]
I've made a nested list like this, l = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Now, I want to print all the 1's or 2's from each nested lists into another list r[].
For example r should be, r = [2, 2, 2] or [1, 1, 1]
I've tried follwing,
for i in l:
if(i == 0):
r.append(i)
print(r)
But, it doesn't return anything.
Try this:
for i in l:
for j in i:
if(j == 1):
r.append(j)
print(r)
output:
[1,1,1]
Here i is a sub list in the list l and j is an item in sub list i. So if j is equal to 1 it will get appended to the list r.
I have the following dictionary {44: [0, 1, 0, 3, 6]} and need to convert this to dict1 = {44: {0:0, 1:1, 2:0, 3:3, 4:6}} but my current for loop doesn't work:
maxnumbers = 5 #this is how many values are within the list
for i in list(range(maxnumbers)):
for k in list(dict1.keys()):
for g in dict1[k]:
newdict[i] = g
print(num4)
Can you help me? Thanks in advance.
You can use a dictionary comprehension with enumerate:
d = {44: [0, 1, 0, 3, 6]}
{k:dict(enumerate(v)) for k,v in d.items()}
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
Use a simple nested dictionary-comprehension that uses enumerate:
d = {44: [0, 1, 0, 3, 6]}
print({k: {i: x for i, x in enumerate(v)} for k, v in d.items()})
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
a = {44: [0, 1, 0, 3, 6]}
a= {i:{j:a[i][j] for i in a for j in range(len(a[i]))}}
print(a)
output
{44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
Why your current implementation doesn't work:
for i in list(range(maxnumbers)):
for k in list(dict1.keys()):
for g in dict1[k]:
# this will iterate over all of the values in
# d1[k] and the i: v pair will be overwritten by
# the last value
newdict[i] = g
Taken in steps, this would look like:
# for value in [0, 1, 0, 3, 6]: Just take this set of values as an example
# first, value is 0, and say we are on i = 1, in the outer for loop
newdict[1] = 0
# Then it will progress to value = 1, but i has not changed
# which overwrites the previous value
newdict[1] = 1
# continues until that set of values is complete
In order to fix this, you'll want i and the values of dict1[k] to increment together. This can be accomplished with zip:
for index, value in zip(range(maxnumbers), dict1[k]):
newdict[index] = value
Also, if you need access to both the keys and values, use dict.items():
for k, values in dict1.items():
# then you can use zip on the values
for idx, value in zip(range(maxnumbers), values):
However, the enumerate function already facilitates this:
for k, values in dict1.items():
for idx, value in enumerate(values):
# rest of loop
This is more robust, since you don't have to find what maxnumbers is ahead of time.
To do this in the traditional for loop that you've been using:
new_dict = {}
for k, v in dict1.items():
sub_d = {} # create a new sub_dictionary
for i, x in enumerate(v):
sub_d[i] = x
# assign that new sub_d as an element in new_dict
# when the inner for loop completes
new_dict[k] = sub_d
Or, more compactly:
d = {44: [0, 1, 0, 3, 6]}
new_d = {}
for k, v in d.items():
new_d[k] = dict(enumerate(v))
Where the dict constructor will take an iterable of 2-element tuples as an argument, which enumerate provides
If you have a dictionary of integers:
d = {
1:[0],
2:[1],
3:[0,1,2,3,4],
4:[0],
5:[1],
6:[0,1,2,3,4],
11:[0],
22:[1],
33:[0,1,2,3,4],
44:[0],
55:[1],
66:[0,1,2,3,4]
}
You want to:
Validate that the keys are between 0 and 25.
Delete any keys that are outside of the range as they are not valid and will ruin the data set.
Dictionary keys are not naturally sorted.
Given, how would validate that your keys are in the required range?
My try:
for x,y in d.items():
if x<0 or x>25:
del d[x]
When ran I get the error:
RuntimeError: dictionary changed size during iteration
How would I compensate for this?
In your example, you are mutating the d while looping through it. This is bad.
The easiest way to do this if you don't need to change the original d is to use a dictionary comprehension:
d = {k: v for k, v in d.items() if 0 <= k <= 25}
If you want to delete keys while iterating, you need to iterate over a copy instead and pop keys that don't hold to your condition:
d = {1:[0], 2:[1], 3:[0,1,2,3,4], 4:[0], 5:[1], 6:[0,1,2,3,4], 11:[0], 22:[1], 33:[0,1,2,3,4], 44:[0], 55:[1], 66:[0,1,2,3,4]}
for k in d.copy(): # or list(d)
if not 0 <= k <= 25:
d.pop(k) # or del d[k]
Which Outputs:
{1: [0], 2: [1], 3: [0, 1, 2, 3, 4], 4: [0], 5: [1], 6: [0, 1, 2, 3, 4], 11: [0], 22: [1]}
As others have shown, reconstructing a new dictionary is always an easy way around this.
You can use a basic dict comprehension here:
{k: d[k] for k in d if 0 <= k <= 25}
Or even a functional approach with filter():
dict(filter(lambda x: 0 <= x[0] <= 25, d.items()))
You can use a dictionary comprehension:
d = { 1:[0], 2:[1], 3:[0,1,2,3,4], 4:[0], 5:[1], 6:[0,1,2,3,4], 11:[0], 22:[1], 33:[0,1,2,3,4], 44:[0], 55:[1], 66:[0,1,2,3,4] }
new_d = {a:b for a, b in d.items() if a <= 25 and a >= 0}
Output:
{1: [0], 2: [1], 3: [0, 1, 2, 3, 4], 4: [0], 5: [1], 6: [0, 1, 2, 3, 4], 11: [0], 22: [1]}