Python set/tuple operations iteration - python

I have a set of tuple(a, b, c). How can I return a list of all a inside this set? Is there something like .keys() as dictionaries have?

myList = [tup[0] for tup in mySet]
They're not "keys" per se.

Use a list comprehension:
data = set([(1, 2, 3), (4, 5, 6)])
all_a = [a for a, b, c in data]
Or if the tuples can be of varying length:
all_a = [t[0] for t in data]

Related

Iterate consecutive elements in a list in Python such that the last element combines with first

I have a list:
L = [1,2,3,4,5,6,7,8]
I want to iterate consecutive elements in the list such that, when it comes to last element i'e 8 it pairs with the first element 1.
The final output I want is:
[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,1]
I tried using this way:
for first,second in zip(L, L[1:]):
print([first,second])
But I am getting only this result:
[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8]
How do I make a pair of last element with first? I have heard about the negative indexing property of a list.
You can simply extend the second list in zip() with a list with only the first item, something like:
for first, second in zip(L, L[1:] + L[0:1]): # or simply zip(L, L[1:] + L[:1])
print([first, second])
You can use cycle to cycle the lists (in combination with islice to skip the first element):
from itertools import cycle, islice
L = [1,2,3,4,5,6,7,8]
rest_L_cycled = islice(cycle(L), 1, None)
items = zip(L, rest_L_cycled)
print(list(items))
This is easily extensible. Note that it relies on the fact that zip halts on the shorter list (the second argument is an infinite cycle). It also does everything lazily and does not create any intermediate list (well, except for the printed list) :-)
You can just append the front element(s) to the back.
for first,second in zip(L, L[1:] + L[:1]):
print([first,second])
You can also iterate through the indexes of L, and for the index of the second item of the output tuples, simply use the remainder of the length of L:
[(L[i], L[(i + 1) % len(L)]) for i in range(len(L))]
You can simply concatenate the list resulting from zip(L, L[1:]) with the pair formed by the last element L[-1] and first one L[0] and iterate over the result
for first,second in zip(L, L[1:]) + [(L[-1],L[0])]:
print ([first,second])
It gives the desired outcome.
It's not a one-liner, but:
>>> L = [1,2,3,4,5,6,7,8]
>>> z = list(zip(L[:-1], L[1:]))
>>> z.append((L[-1], L[0]))
>>> z
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 1)]
for i in range(len(L)):
first = L[i]
second = L[(i+1) % len(L)]
You can simply use itertools.zip_longest with a fillvalue of the first item.
from itertools import zip_longest
list(map(tuple, zip_longest(L, L[1:], fillvalue=L[0]))
This is a version (over-)using itertools:
from itertools import islice, cycle
L = [1,2,3,4,5,6,7,8]
for a, b in zip(L, islice(cycle(L), 1, None)):
print(a, b)
The idea is to cycle over the second argument - that way zip runs until L itself is exhausted. This does not create any new lists.

Convert list into a list of 2-tuples

I have a list:
list = [1, 2, 3]
I want to get this list and add a tuple so this list becomes like this
T_list = [(1,x), (2, x), (3,x)]
How do I do it?
Use a simple list comprehension to do this:
>>> your_list = [1, 2, 3]
>>> x = 100
>>> your_list_with_tuples = [(k, x) for k in your_list]
>>> your_list_with_tuples
Output
[(1, 100), (2, 100), (3, 100)]
Also, don't name your variables list, dict, etc, because they shadow the builtin types/functions.
A list comprehension would do the trick:
t_list = [(y,x) for y in original_list]
Also, the commenter is right. Don't name your lists list. It's a built in function. Using it for something else could cause problems down the line.
Here's my attempt, although I'm not an expert.
lis = [1,2,3]
tup = (4, 5, 6)
new_tup = tuple(lis)
new_lis = []
for i in range(0,3):
data = (new_tup[i],tup[i])
new_lis.append(data)
print(new_lis)

merge two lists python

I have two lists:
a = [(1,2,3),(4,5,6)]
b = [7,8]
I want to merge it into:
c = [(1,2,3,7),(4,5,6,8)]
I used zip(a,b) but the result does not seem correct. Can anyone help?
zip() will just pair up the tuples and the integers. You also need to concatenate the tuple and the new item:
c = [aa + (bb,)
for aa, bb in zip(a, b)]
>>> a = [(1,2,3),(4,5,6)]
>>> b = [7,8]
>>> c = zip(*a)+[b] #c looks like [(1,4),(2,5),(3,6),(7,8)]
>>> print zip(*c) #zip it back together
[(1, 2, 3, 7), (4, 5, 6, 8)]
>>>
Try
map ( lambda x: x[0]+(x[1],), zip(a,b))
And yet another version:
from itertools import izip
[x+(y,) for x,y in izip(a,b)]
Should be efficient and it expresses what you are really doing in a readable way.
And yet another:
map(lambda t, e: t + (e,), a, b)
No need to zip and unpack; map can take both lists at once.
print((a[0]+(b[0],),a[1]+(b[1],)))
This seems clear to me:
[x + (b[i],) for i,x in enumerate(a)]

How To Merge an Arbitrary Number of Tuples in Python?

I have a list of tuples:
l=[(1,2,3),(4,5,6)]
The list can be of arbitrary length, as can the tuples. I'd like to convert this into a list or tuple of the elements, in the order they appear:
f=[1,2,3,4,5,6] # or (1,2,3,4,5,6)
If I know the at development time how many tuples I'll get back, I could just add them:
m = l[0] + l[1] # (1,2,3,4,5,6)
But since I don't know until runtime how many tuples I'll have, I can't do that. I feel like there's a way to use map to do this, but I can't figure it out. I can iterate over the tuples and add them to an accumulator, but that would create lots of intermediate tuples that would never be used. I could also iterate over the tuples, then the elements of the tuples, and append them to a list. This seems very inefficient. Maybe there's an even easier way that I'm totally glossing over. Any thoughts?
Chain them (only creates a generator instead of reserving extra memory):
>>> from itertools import chain
>>> l = [(1,2,3),(4,5,6)]
>>> list(chain.from_iterable(l))
[1, 2, 3, 4, 5, 6]
l = [(1, 2), (3, 4), (5, 6)]
print sum(l, ()) # (1, 2, 3, 4, 5, 6)
reduce(tuple.__add__, [(1,2,3),(4,5,6)])
tuple(i for x in l for i in x) # (1, 2, 3, 4, 5, 6)
Use the pythonic generator style for all of the following:
b=[(1,2,3),(4,5,6)]
list = [ x for x in i for i in b ] #produces a list
gen = ( x for x in i for i in b ) #produces a generator
tup = tuple( x for x in i for i in b ) #produces a tuple
print list
>> [1, 2, 3, 4, 5, 6]
>>> from itertools import chain
>>> l = [(1,2,3),(4,5,6)]
>>> list(chain(*l))
[1, 2, 3, 4, 5, 6]
You can combine the values in a list using the .extend() function like this:
l = [(1,2,3), (4,5,6)]
m = []
for t in l:
m.extend(t)
or a shorter version using reduce:
l = [(1,2,3), (4,5,6)]
m = reduce(lambda x,y: x+list(y), l, [])

Sorting a list in Python using the result from sorting another list [duplicate]

This question already has answers here:
Sorting list based on values from another list
(20 answers)
Closed 8 years ago.
I have the two lists in Python
list_1 = [5, 2, 8];
list_2 = ['string1', 'string2', 'string3']
I would like to sort the fist list and use the result to sort the second list.
In other words, the result should be:
# Sorted in descending order
list_1_sorted = [8, 5, 2];
list_2_sorted = ['string3', 'string1', 'string2'];
I know how to sort each of these lists individually, but how I can permute one list using the permutation of indices resulting from sorting the other list?
Schwartzian transform
list_1_sorted, list_2_sorted = zip(*sorted(zip(list_1, list_2),
key=operator.itemgetter(0), reverse=True))
Zip the lists together, sort, unzip the lists:
together = zip(list_1, list_2)
sorted_together = sorted(together)
list_1_sorted = [x[0] for x in sorted_together]
list_2_sorted = [x[1] for x in sorted_together]
What's happening here is that zip creates a list of tuples, with the elements you want the list to be sorted by being the first elements:
>>> a = [1,3,7,3,2]
>>> b = ["one","two",'three','four','five']
>>> zip(a,b)
[(1, 'one'), (3, 'two'), (7, 'three'), (3, 'four'), (2, 'five')]
Then when you sort them, they elements stay paired:
>>> sorted(zip(a,b))
[(1, 'one'), (2, 'five'), (3, 'four'), (3, 'two'), (7, 'three')]
Then all that's left is to unpack these lists.
You can use zip:
>>> list_1 = ['string1', 'string2', 'string3']
>>> list_2 = [5, 2, 8]
>>> s = sorted(zip(list_2, list_1), reverse=True)
>>> list_1_sorted = [e[1] for e in s]
>>> list_2_sorted = [e[0] for e in s]
>>> list_1_sorted
['string3', 'string1', 'string2']
>>> list_2_sorted
[8, 5, 2]
>>>
#Ignacio's answer is the best, but just in case you need to sort the lists in-place without making new lists, you can try this:
import itertools
list_enumerate = itertools.count()
list_2.sort(reverse=True, key=lambda k: list_1[next(list_enumerate)])
list_1.sort(reverse=True)
print list_1
print list_2
Note that I do not think there is any guarantee that the key function is called for each list item in order (which is necessary for this to work), so this is a risky method to use.

Categories