L = ["5", "0 1", "0 2", "1 3", "2 3", "2 4", "3 4"]
Each number represents a person. So, there are five people from 0 to 4 in the list. L[0]
always shows how many people are in the list.
L1 = [(0,[1,2]), (1, [3]), (2, [3,4]), (3, [4])]
The person "0"
is paired with 1
and 2
. So, it has a list of 1, 2
in a tuple. My approach to get the result above is to compare the first character in L[1]
to the end of the list. If the first letter in L[1]
matches with the first letter in L[2]
, it bundles the second letter in L[2]
with the second letter in L[1]
. Finally, the new list is paired with 0
in a tuple. By the way, I cannot come up with such thing that can check the first letter in strings. I am not sure if this approach is right or not.
I am struggling to make such list L1
above. Could anyone let me know if my approach to this question is right? If it is wrong, please briefly give me a hint to solve this.
Using list comprehension
Created a list in the required range, considering L[0]
Checks for matches between the element and the other items using startswith
L = ["5", "0 1", "0 2", "1 3", "2 3", "2 4", "3 4"]
L1 = [(0,[1,2]), (1, [3]), (2, [3,4]), (3, [4])] # required list
L2 = [ (i, [ int(x[-1]) for x in L if str(x).startswith(str(i)) ]) for i in range(int(L[0])-1) ]
Output
[(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
[(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
Probably the best thing is to first use a defaultdict
:
from collections import defaultdict
from itertools import islice
result = defaultdict(list)
for li in islice(L,1,None):
h, *others = map(int,li.split())
for other in others:
result[h].append(other)
Or a version that works for python-2.x :
from collections import defaultdict
from itertools import islice
result = defaultdict(list)
for li in islice(L,1,None):
data = map(int,li.split())
h = data[0]
for other in data[1:]:
result[h].append(other)
and then we obtain the items
of that dictionary:
L1 = list(result.items())
This produces:
>>> L1
[(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
Note that in this case the items are not ordered: since a dictionary in Python usually has no order (the latest implementations in CPython have, but this is seen as an implementation detail).
But converting the dictionary back into a list is not logical, since the advantage of a dictionary is a fast lookup (in O(1) , constant time).
We can make the last part more elegant by writing:
from collections import defaultdict
result = defaultdict(list)
for li in islice(L,1,None):
h, *others = map(int,li.split())
result[h] += others
Instead of list, go with dict and use this pattern without importing any external module.
L = ["5", "0 1", "0 2", "1 3", "2 3", "2 4", "3 4"]
final_dict={}
new=[]
for item in L:
if not len(item)<2:
if int(item[0]) not in final_dict:
final_dict[int(item[0])]=[int(item[2])]
else:
final_dict[int(item[0])].append(int(item[2]))
print(final_dict)
output:
{0: [1, 2], 1: [3], 2: [3, 4], 3: [4]}
or if you want the result in the list then add this line end of above code:
print([(key,value) for key,value in final_dict.items()])
output:
[(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
I would suggest you use a form of dictionary
for easier processing of the data later on. So here, defualtdict
would be best utilized.
>>> from collections import defaultdict
>>> L = ["5", "0 1", "0 2", "1 3", "2 3", "2 4", "3 4"]
>>> n = int(L.pop(0)) #number of people
>>> d = defaultdict(list)
>>> for ele in L:
x, y = map(int, ele.split())
d[x].append(y)
>>> d
=> defaultdict(<class 'list'>, {0: [1, 2], 1: [3], 2: [3, 4], 3: [4]})
If neccessary to have that list
format, use dict.items()
and type cast it to list
>>> l1 = list(d.items())
>>> l1
=> [(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
Here is an itertools.groupy
solution. (The commented out line also considers reverse pairs.)
import itertools as it
import operator as op
def L1(L):
# split pairs
L = [p.split() for p in L[1:]]
# convert to int
L = [(int(P1), int(P2)) for P1, P2 in L]
LL = sorted(L)
# # add reversed and sort
# LL = sorted(L + [P[::-1] for P in L])
# group by first element
res = it.groupby(LL, op.itemgetter(0))
# make proper lists
return [(k, [P[1] for P in v]) for k, v in res]
Output (for the example L
):
[(0, [1, 2]), (1, [3]), (2, [3, 4]), (3, [4])]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.