This is my first question here =):
My problem is what is stated in the title. I want to simply sort a list of tuples with 2 elements. It should work with sorted but it still returns the unsorted List,... it seems to do nothing.
Input:
#"L =[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]" Its an example.
for line in stdin:
L = [int(i) for i in line.split()]
n = L[0]
V = [i for i in range(n)]
edgelist = L[1:]
EDGE = [(edgelist[i],edgelist[i+1]) for i in range(0,len(edgelist)-1,2) ]
mK = missingKnots(edgelist)
EDGE = sorted(EDGE)
EDGE = list(set(EDGE))
Output:
[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
Should be:
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Unsorted =(.
Thanks for reading!
Sort and return new list:
>>> L =[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
>>> sorted(L)
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Sort in place:
>>> L.sort()
>>> L
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Don't do the set() afterward. Sets are unordered.
>>> list(set(L))
[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)] # now it's messed up again.
Ideally, to sort and remove duplicates:
>>> L = [(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5), (0, 1)]
>>> sorted(set(L))
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
With lambda expression, you can customise the rules of sorting.
EDGE = [(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
EDGE = sorted(EDGE, key=lambda x: (x[0],x[1]) )
print EDGE
result:
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Related
I have a list of tuples:
[(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
and I want to sum the right-side of tuples where the left-side is equal, and to put it in another tuples-list, so for the above list i'll get:
[(0,2),(1,1),(2,1),(3,2),(4,3),(5,2)]
I tried this:
k=0
for i,TCtup in enumerate(wordsMatchingList):
if wordsMatchingList[i][0]==k:
TC_matches+=wordsMatchingList[i][1]
print("k: {} /// TC_matches: {}".format(k,TC_matches)) #for checking
else:
groupedWordsMatchingList.append(tuple((k,TC_matches)))
TC_matches=0
k+=1
but from k=1 it just loop one time less for every k because of the else condition.
thank you
If your tuples are guaranteed to come in order like this—all the (0, x), then all the (1, x), etc.—you can use groupby:
>>> xs = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
>>> from itertools import groupby
>>> from operator import itemgetter
>>> groups = groupby(xs, key=itemgetter(0))
>>> ys = [(key, sum(map(itemgetter(1), group))) for key, group in groups]
If they aren't, but you can sort them (you have a list, not just an arbitrary iterable, and it isn't so huge that log-linear time will be too expensive):
>>> groups = groupby(sorted(xs, key=itemgetter(0)), key=itemgetter(0))
If you can't sort them, you can manually build up the totals as you go:
>>> from collections import Counter
>>> totals = Counter()
>>> for k, v in xs:
... totals[k] += v
>>> ys = list(totals.items())
yet another way,
t.sort(key=lambda x: x[0]) #sort before groupby (required)
g=itertools.groupby(t, lambda x: x[0])
new_l = []
for k,v in g:
new_l.append((k, sum([x[1] for x in v])))
Another approach is using a defaultdict (from collections) and to iterate the list of tuples.
from collections import defaultdict
lst = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
d = defaultdict(int)
for (u,v) in lst:
d[u]+=v
# list(d.items()) [(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
I'd recommend using a library with a groupby function. pandas, for instance, can be useful
>>> s = pd.DataFrame(list_)
>>> s.groupby(0, as_index=False).sum().agg(tuple,1).tolist()
[(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
In [5]: [(j, sum([i[1] for i in a if i[0] == j])) for j in set([i[0] for i in a])]
Out[5]: [(0, 2), (1, 1), (2, 1), (3, 2), (4, 3), (5, 2)]
lst = [(0, 1), (0, 1), (0, 0), (0, 0), (1, 0), (1, 0), (1, 1), (1, 0), (1, 0), (2, 0), (2, 1), (2, 0), (3, 0), (3, 1), (3, 1), (3, 0), (3, 0), (4, 0), (4, 1), (4, 0), (4, 1), (4, 1), (5, 0), (5, 0), (5, 1), (5, 1)]
[(i,sum([q[1] for q in lst if q[0] == i])) for i in range(lst[-1][0]+1)]
gives:
[(0,2),(1,1),(2,1),(3,2),(4,3),(5,2)]
How can I rearrange [(0, 4), (1, 3)] to (0, 1), (4, 3), in other words group first coordinates together and second coordinates together (order maintained left to right). I need to do this for a large list of, exampled below
c = [[(0, 4), (1, 3)],
[(0, 4), (1, 5)],
[(1, 3), (2, 2)],
[(1, 3), (2, 4)],
[(1, 5), (2, 2)],
[(1, 5), (2, 6)],
...]
So that the end result is
[[(0, 1), (4, 3)],
[(0, 1), (4, 5)],
[(1, 2), (3, 2)],
[(1, 2), (3, 4)],
[(1, 2), (5, 2)],
[(1, 2), (5, 6)],
...
]
How about
end_result = [[(w, y), (x, z)] for [(w, x), (y, z)] in c]
?
I'm trying generate a bunch of pairs from a list in python --- I figured out a way of doing it using for loops:
keys = range(10)
keypairs = list()
for i in range(len(keys)):
for j in range(i+1, len(keys)):
keypairs = keypairs + [(keys[i], keys[j])]
Is there a more "python style" way of doing this? My method doesn't seem very elegant ...
You want two range loops, one from 0 to n and the inner from each i of the first range + 1 to n using a list comp:
n = 10
pairs = [(i, j) for i in range(n) for j in range(i+1, n)]
from pprint import pprint as pp
pp(pairs,compact=True)
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 2),
(1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 3), (2, 4), (2, 5),
(2, 6), (2, 7), (2, 8), (2, 9), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9),
(4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 6), (5, 7), (5, 8), (5, 9), (6, 7),
(6, 8), (6, 9), (7, 8), (7, 9), (8, 9)]
Which exactly matches your output.
You want to check list comprehension:
sorted([(i, j) for j in range(10) for i in range(10) if j > i])
I would use itertools for that. Check combinations_with_replacement and combinations methods.
And here is the code sample:
import itertools
list(itertools.combinations(keys, 2))
EDITED: Yes, I noticed that it should be combinations, not combinations_with_replacements.
For example:
alist=[[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 1), (2, 0), (1, 0), (3, 0)],
[(0, 2), (0, 3), (1, 3)],
[(0, 4), (1, 4), (2, 4), (0, 5), (0, 6), (1, 6), (2, 6), (3, 6)],
[(1, 5)],
[(2, 3), (3, 3), (3, 4), (3, 5), (2, 5), (3, 2), (3, 1)]]
for i in dlist:
print(len(i))
print(max(len(i))) #this gives me error
output:
5
9
3
8
1
7
I wanted to print out 9 as my output from the above list. How am I able to print the result?
Somewhat more terse
len(max(alist,key=len))
If you can be sure your nesting is only one level (that is, a list of lists):
print max(len(sublist) for sublist in alist)
functional style using map:
print max(map(len, alist))
If you want the actual index of the longest sublist:
max(((i,l) for i,l in enumerate(alist)), key=lambda t: len(t[1]))[0]
Or, as stated in comments:
max(enumerate(alist), key=lambda t: len(t[1]))[0]
In Python, is there a better way to get the set of combinations of n elements from a k-element set than nested for loops or list comprehensions?
For example, say from the set [1,2,3,4,5,6] I want to get [(1,2),(1,3),(1,4),(1,5),(1,6),(2,3),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6)]. Is there a better of of making it than
nums=[1,2,3,4,5,6]
doubles=[]
for a in nums:
for b in nums[a+1:]
doubles.append((a,b))
? It's okay if the elements of the list we end up with are sets, tuples, or lists; I just feel there should be an easier way to do this.
You can use itertools.combinations:
>>> from itertools import combinations
>>> nums = [1,2,3,4,5,6]
>>> list(combinations(nums, 2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
The itertools module has a lot of really powerful tools that can be used in situations like this. In this case, you want itertools.combinations. Some other ones that you might find useful are itertools.combinations_with_replacement and itertools.permutations.
Example:
>>> import itertools
>>> list(itertools.combinations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
>>> list(itertools.combinations_with_replacement(range(1,7),2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)]
>>> list(itertools.permutations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5)]
You could use the itertools module
import itertools
alphabet = ['1','2','3','4','5','6']
combos = list(itertools.combinations(alphabet, 2))
print combos