Related
During communities' detection I am trying to remove duplicates nodes from lists of lists (aimed to calculate ARI).
What I have – few dozen lists inside one list with different dimensions:
lst_of_lts= [[5192, 32896, 34357, 34976, 36683, 43315], … ,[19, 92585, 94137, 98381, 99041, 100395, 101100, 109759]]
What I am running:
import itertools
Lst_of_lts.sort()
Lst_of_lts_2 = list(k for k,_ in itertools.groupby(Lst_of_lts))
Lst_of_lts_nodops= [list(i) for i in {tuple(sorted(i)) for i in Lst_of_lts_2}]
For some reason, it doesn’t remove duplicates.
The dimensions remain the same-
Any suggestions?
Also tried many options such as:
Remove duplicate items from lists in Python lists and
Remove duplicated lists in list of lists in Python
If you are removing duplicates just in the list itself, you can use set.
a = np.random.randint(0,5,(10,10)).tolist()
a
Out[128]:
[[0, 3, 0, 2, 4, 4, 0, 0, 3, 3],
[2, 4, 0, 2, 4, 2, 2, 4, 3, 1],
[3, 2, 0, 1, 2, 0, 2, 0, 2, 1],
[3, 1, 4, 1, 0, 1, 4, 4, 3, 4],
[2, 0, 1, 1, 0, 4, 1, 4, 2, 3],
[0, 0, 1, 3, 4, 3, 1, 3, 0, 1],
[1, 2, 0, 2, 1, 3, 4, 2, 2, 0],
[3, 3, 2, 2, 0, 4, 1, 1, 0, 0],
[0, 1, 3, 0, 4, 4, 2, 1, 1, 4],
[0, 1, 4, 4, 0, 1, 3, 2, 1, 1]]
[list(set(i)) for i in a]
Out[129]:
[[0, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3],
[0, 1, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]
Or if you want to preserve the order of the element, you can use dict.fromkeys
[list(dict.fromkeys(i)) for i in a]
Out[133]:
[[0, 3, 2, 4],
[2, 4, 0, 3, 1],
[3, 2, 0, 1],
[3, 1, 4, 0],
[2, 0, 1, 4, 3],
[0, 1, 3, 4],
[1, 2, 0, 3, 4],
[3, 2, 0, 4, 1],
[0, 1, 3, 4, 2],
[0, 1, 4, 3, 2]]
This is my code:
b = [6 * [1, 3, 4, 2],
4 * [2, 1, 4, 3],
3 * [3, 4, 2, 1],
4 * [4, 2, 1, 3],
4 * [4, 3, 2, 1],
]
Which returns an array which has 6X4=24 elements in the first line 4X4=16 in the second etc...
What i want to achieve is adding the exact same line multiple times like:
1, 3, 4, 2
1, 3, 4, 2
1, 3, 4, 2
1, 3, 4, 2
1, 3, 4, 2
1, 3, 4, 2 #6 tines the first line
2, 1, 4, 3
2, 1, 4, 3
2, 1, 4, 3
2, 1, 4, 3 # 4 times the second
..........
but of course by not copying the same line again and again
Try:
b = [
*[[1, 3, 4, 2] for _ in range(6)],
*[[2, 1, 4, 3] for _ in range(4)],
*[[3, 4, 2, 1] for _ in range(3)],
*[[4, 2, 1, 3] for _ in range(4)],
*[[4, 3, 2, 1] for _ in range(4)],
]
print(b)
Prints:
[
[1, 3, 4, 2],
[1, 3, 4, 2],
[1, 3, 4, 2],
[1, 3, 4, 2],
[1, 3, 4, 2],
[1, 3, 4, 2],
[2, 1, 4, 3],
[2, 1, 4, 3],
[2, 1, 4, 3],
[2, 1, 4, 3],
[3, 4, 2, 1],
[3, 4, 2, 1],
[3, 4, 2, 1],
[4, 2, 1, 3],
[4, 2, 1, 3],
[4, 2, 1, 3],
[4, 2, 1, 3],
[4, 3, 2, 1],
[4, 3, 2, 1],
[4, 3, 2, 1],
[4, 3, 2, 1],
]
You can also put it in one line with
b = 6*[[1, 3, 4, 2]] + 4*[[2, 1, 4, 3]] + 3*[[3, 4, 2, 1]] + 4*[[4, 2, 1, 3]] + 4* [[4, 3, 2, 1]])
print(b)
Only two steps if you don't want to change how b was created.
import numpy as np
B = np.concatenate(b).ravel()
b = np.reshape(B,(21,4))
You can use a list comprehension of a list comprehension to repeat y times your x lists (from bb and aa, respectively)
The notation is a bit strange, the "center" one is the outer element, then it expands on the right.
Advantage: numpy not required, and it will work for any size entries, unlike other answers "harcoding" the rows
aa=[[1, 3, 4, 2],
[2, 1, 4, 3],
[3, 4, 2, 1],
[4, 2, 1, 3],
[4, 3, 2, 1]]
bb=[6,4,3,4,4]
xx = [x for x,y in zip(aa,bb) for _ in range(y) ]
returns:
[[1, 3, 4, 2], [1, 3, 4, 2], [1, 3, 4, 2], [1, 3, 4, 2], [1, 3, 4, 2], [1, 3, 4, 2], [2, 1, 4, 3], [2, 1, 4, 3], [2, 1, 4, 3], [2, 1, 4, 3], [3, 4, 2, 1], [3, 4, 2, 1], [3, 4, 2, 1], [4, 2, 1, 3], [4, 2, 1, 3], [4, 2, 1, 3], [4, 2, 1, 3], [4, 3, 2, 1], [4, 3, 2, 1], [4, 3, 2, 1], [4, 3, 2, 1]]
It can be done systematically by pairing the factors and the sublists and multiplying them together. Then flat the list.
Here a hacky-way
b = [[1, 3, 4, 2],
[2, 1, 4, 3],
[3, 4, 2, 1],
[4, 2, 1, 3],
[4, 3, 2, 1],
]
factors = [6, 4, 3, 4, 4]
print(sum(f*[l] for f, l in zip(factors, b), []))
The flattening part (chaining of lists) is done with sum( , []) but is not performant (and designed for that)... but still useful, in my opinion, to test some small stuffs on the fly. The list chaining have to be done with i.e. itertools.chain. Here an example
import itertools as it
...
list(it.chain.from_iterable(f*[l] for f, l in zip(factors, b)))
# or (for many iterators)
list(it.chain(*(f*[l] for f, l in zip(factors, b))))
# or with repeat
list(it.chain.from_iterable(it.starmap(it.repeat, zip(b, factors))))
# or (another) with repeat
list(it.chain.from_iterable(map(it.repeat, b, factors))
# or ...
list(it.chain.from_iterable(map(list.__mul__, ([i] for i in b) , factors)))
# or with reduce
import functools as fc
list(fc.reduce(lambda i, j: i + j, zip(b, factors)))
My data is as follows,
data = [[2, 1, 2, 2], [2, 2, 1, 5], [1, 2, 2, 2], [2, 1, 2, 5], [2, 5, 2, 1]]
I would like to transform this such that there is a 0 at 0, 1, 2, 3 and 4th positions of the internal lists and get it look like below,
new_Data = [[0, 2, 1, 2, 2], [2, 0, 2, 1, 5], [1, 2, 0, 2, 2], [2, 1, 2, 0, 5], [2, 5, 2, 1, 0]]
I have tried using the following method,
a = 0
for n in range(len(mRco1)-1):
mRco1[n][n] = [a]
But it does not seem to work.
Can anyone suggest how can I go about this?
Use the list.insert() method
for i in range(len(data)):
data[i].insert(i, 0)
result :
print(data)
>>> [[0, 2, 1, 2, 2], [2, 0, 2, 1, 5], [1, 2, 0, 2, 2], [2, 1, 2, 0, 5], [2, 5, 2, 1, 0]]
You'd like to iterate over the lists in data, and for the n'th list, insert a 0 at position n. You can use the insert function for that, and define the following loop:
for i in range(len(data)):
data[i].insert(i, 0)
I'm working with lists and something came up, so let's say I have a 3D list and I want to create a 4D list, so every two positions in the inner lists split, here is what I tried
mylist = [[[0, 2, 1], [0, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]],
[[0, 2, 1], [0, 4, 2, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]]]
newlist = [mylist[i: i + 2] for i in range(0, len(mylist), 2)]
print(newlist)
newlist = [[[[0, 2, 1], [0, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]],
[[0, 2, 1], [0, 4, 2, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
but I was expecting something like:
newlist = [[[[0, 2, 1], [0, 3, 1]], [[0, 4, 3, 1], [0, 4, 3, 1]], [[0, 3, 2, 1], [0, 2, 3, 4, 1]]],
[[0, 2, 1], [0, 4, 2, 3, 1]], [[0, 4, 3, 1], [0, 4, 3, 1]], [[0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
I believe I'm missing a for in my list comprehension something like:
newlist = [[mylist[j: j + 2] for j in i] for i in range(0, len(my list), 2)]
but I'm having an error and I can't figure it out what is the problem, so any help will appreciated, thank you so much!
Try this:
newlist=[[list(ls) for ls in zip(i[::2], i[1::2])] for i in mylist]
print(newlist)
Output:
[[[[0, 2, 1], [0, 3, 1]],
[[0, 4, 3, 1], [0, 4, 3, 1]],
[[0, 3, 2, 1], [0, 2, 3, 4, 1]]],
[[[0, 2, 1], [0, 4, 2, 3, 1]],
[[0, 4, 3, 1], [0, 4, 3, 1]],
[[0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
Here is a possible solution. You were very close!
newlist = [[lst[i:i+2] for i in range(0, len(lst), 2)] for lst in mylist]
I'm trying to find the paths that a user could take through a website. I have represented my graph using this format:
graph = { 0 : [1, 2],
1 : [3, 6, 0],
2 : [4, 5, 0],
3 : [1],
4 : [6, 2],
5 : [6, 2],
6 : [1, 4, 5]}
I have implemented a depth first algorithm, but it needs a change for it to be useful. It needs to return the path and not just the nodes in the order it goes to them.
visitedList = [[]]
def depthFirst(graph, currentVertex, visited):
visited.append(currentVertex)
for vertex in graph[currentVertex]:
if vertex not in visited:
depthFirst(graph, vertex, visited)
return visited
traversal = depthFirst(graph, 0, visitedList)
print('Nodes visited in this order:')
print(visitedList)
That function returns this:
[[], 0, 1, 3, 6, 4, 2, 5]
Whereas I want something like this:
[[0, 1, 3], [0, 1, 6], [0, 2, 4, 6], [0, 2, 5, 6]]
When passing a list in python it does not deep copy. Using list.copy() can really help here. I'm not sure this is what you wanted but here is the code:
visitedList = [[]]
def depthFirst(graph, currentVertex, visited):
visited.append(currentVertex)
for vertex in graph[currentVertex]:
if vertex not in visited:
depthFirst(graph, vertex, visited.copy())
visitedList.append(visited)
depthFirst(graph, 0, [])
print(visitedList)
It returns all the paths.
[[], [0, 1, 3], [0, 1, 6, 4, 2, 5], [0, 1, 6, 4, 2], [0, 1, 6, 4], [0, 1, 6, 5, 2, 4], [0, 1, 6, 5, 2], [0, 1, 6, 5], [0, 1, 6], [0, 1], [0, 2, 4, 6, 1, 3], [0, 2, 4, 6, 1], [0, 2, 4, 6, 5], [0, 2, 4, 6], [0, 2, 4], [0, 2, 5, 6, 1, 3], [0, 2, 5, 6, 1], [0, 2, 5, 6, 4], [0, 2, 5, 6], [0, 2, 5], [0, 2], [0]]
List copy worked for me in python3.