Extract values from list and make tuples - python

I need a simple thing but I cannot do it:
list = 'SBEDFG'
I need as output:
[(S,B),(B,E),(E,D),(D,F),(F,G)]
This is what I tried:
[(list[ind],list[ind+1]) for ind,i in list]
But it gives me this error:
ValueError: need more than 1 value to unpack
Can you help me? Thanks!

You can simply use zip() function like this:
>>>l = 'SBEDFG'
>>>zip(l,l[1:])
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
With Python 3.X you'll need to convert the zip result to a list:
#Python 3.X
>>>l = 'SBEDFG'
>>>list(zip(l,l[1:]))
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
With list comprehension I would do it with range() function:
>>>[(l[i],l[i+1]) for i in range(len(l)-1)]
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
Hope this helps!

try this
>>> [(list[i-1], list[i]) for i in range(1, len(list))]
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]

>>>b=[]
>>> for ind,i in enumerate(list):
... if ind < len(list)-1:
... b.append((list[ind],list[ind+1]))
...
>>> print b
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]

Related

what is optimal solution to get actual two point combinations with given list? [duplicate]

This question already has answers here:
How to find all combinations of two numbers in a list? [duplicate]
(2 answers)
combinations with two elements
(3 answers)
Closed 1 year ago.
I have a list something like this and I want all combinations for two point solution
list1=['a','b','c','d','e','f','g','h']
and I need all 28 combinations from this Expected result:
[['a','b'],['a','c'],['a','d'],['a','e'],['a','f'],['a','g'],['a','h'],
['b','c'],['b','d'],['b','e'],['b','f'],['b','g'],['b','h'],
['c','d'],['c','e'],['c','f'],['c','g'],['c','h'],
['d','e'],['d','f'],['d','g'],['d','h'],
['e','f'],['e','g'],['e','h'],
['f','g'],['f','h'],
['g','h']]
This link is explanation of how 28 combinations.
https://www.calculatorsoup.com/calculators/discretemathematics/combinations.php
I have tried scipy
from scipy.special import comb
comb(8, 2, exact=True)
but it is not giving me the actual combination, It is giving me number of possible combination.
itertools is giving me memory error. as in my list df["ID"] there would be more than 1000 elements.
len(list(combinations(df["ID"].to_list(),5)))
If the I want three point solution then possible combination would be 56
Thanks for your help
Using itertools.combinations returns 28 combinations.
itertools.combinations(list1, 2)
#[('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('a', 'g'), ('a', 'h'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('b', 'g'), ('b', 'h'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('c', 'g'), ('c', 'h'), ('d', 'e'), ('d', 'f'), ('d', 'g'), ('d', 'h'), ('e', 'f'), ('e', 'g'), ('e', 'h'), ('f', 'g'), ('f', 'h'), ('g', 'h')]
len(list(itertools.combinations(list1, 2)))
#28

how can I fix this Towers of Hanoi program for my desired output?

def moveTower(height,fromPole, toPole, withPole):
if height >= 1:
moveTower(height-1,fromPole,withPole,toPole)
moveDisk(fromPole,toPole)
moveTower(height-1,withPole,toPole,fromPole)
def moveDisk(fp,tp):
print("("+fp + "," +tp+')')
moveTower(4,"A","B","C")
I need the output to be a list of tuples (ex: [('A','C'),('A','B'), ...])
Current output:
(A,C)
(A,B)
(C,B)
(A,C)
(B,A)
(B,C)
(A,C)
(A,B)
(C,B)
(C,A)
(B,A)
(C,B)
(A,C)
(A,B)
(C,B)
You should not print the elements. Probably the most elegant is here to construct a generator:
def moveTower(height,fromPole, toPole, withPole):
if height >= 1:
yield from moveTower(height-1,fromPole,withPole,toPole)
yield (fromPole, toPole)
yield from moveTower(height-1,withPole,toPole,fromPole)
yield <expr> here thus emits the value that is constructed by the <expr> in a generator, and yield from <iterable> is used to emit all elements from the <iterable> as elements of this generator.
We can then use list(..) to materialize the generator:
>>> list(moveTower(2, *'ABC'))
[('A', 'C'), ('A', 'B'), ('C', 'B')]
>>> list(moveTower(3, *'ABC'))
[('A', 'B'), ('A', 'C'), ('B', 'C'), ('A', 'B'), ('C', 'A'), ('C', 'B'), ('A', 'B')]
>>> list(moveTower(4, *'ABC'))
[('A', 'C'), ('A', 'B'), ('C', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('A', 'C'), ('A', 'B'), ('C', 'B'), ('C', 'A'), ('B', 'A'), ('C', 'B'), ('A', 'C'), ('A', 'B'), ('C', 'B')]
The simplest modification to your code would be to append them to a list:
result = []
def moveTower(height,fromPole, toPole, withPole):
if height >= 1:
moveTower(height-1,fromPole,withPole,toPole)
moveDisk(fromPole,toPole)
moveTower(height-1,withPole,toPole,fromPole)
def moveDisk(fp,tp):
result.append((fp,tp))
moveTower(4,"A","B","C")
print(result)
Output:
[('A', 'C'), ('A', 'B'), ('C', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('A', 'C'), ('A', 'B'), ('C', 'B'), ('C', 'A'), ('B', 'A'), ('C', 'B'), ('A', 'C'), ('A', 'B'), ('C', 'B')]

Remove particular combinations from itertools.combinations

Suppose we have a pair of tuples where tuples can be of different length. Let's call them tuples t1 and t2:
t1 = ('A', 'B', 'C')
t2 = ('d', 'e')
Now I compute all combinations of length 2 from both tuples using itertools:
import itertools
tuple(itertools.combinations(t1 + t2, 2))
Itertools generator produces all possible combinations, but I need only those which occurs between tuples; the expected output is
(('A', 'd'), ('A', 'e'), ('B', 'd'), ('B', 'e'), ('C', 'd'), ('C', 'e'))
I wonder what is best approach to remove undesired combination.
You need itertools.product :
>>> t1 = ('A', 'B', 'C')
>>> t2 = ('d', 'e')
>>> from itertools import product
>>>
>>> list(product(t1,t2))
[('A', 'd'), ('A', 'e'), ('B', 'd'), ('B', 'e'), ('C', 'd'), ('C', 'e')]
If you are dealing with short tuples you can simply do this job with a list comprehension :
>>> [(i,j) for i in t1 for j in t2]
[('A', 'd'), ('A', 'e'), ('B', 'd'), ('B', 'e'), ('C', 'd'), ('C', 'e')]

Permutation with redundant overlaps? Python

I used itertools to run a permutation on a list that I have.
mylist = [a, b, c, d, e, f]
mypermutations = itertools.permutations(mylist,2)
mypermutations_list = list(mypermutations)
print mypermutations_list
prints:
[(a, b), (a, c), (a, d)...]
However, the permutation list doesn't include (a, a), (b, b), etc. I recognize that's probably because most people don't want such redundant pairings. However, I would like to include such pairings as a control for the program I'm writing.
Is there a way to run a permutation and get these combinations? I have no idea what to use instead of permutations.
You want itertools.product instead:
>>> import itertools
>>> mylist = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list(itertools.product(mylist, repeat=2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ...]
You're looking for itertools.product, it returns the Cartesian product of the iterable:
>>> from itertools import product
>>> list(product('abcdef', repeat=2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'a'), ('c', 'b'), ('c', 'c'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('d', 'a'), ('d', 'b'), ('d', 'c'), ('d', 'd'), ('d', 'e'), ('d', 'f'), ('e', 'a'), ('e', 'b'), ('e', 'c'), ('e', 'd'), ('e', 'e'), ('e', 'f'), ('f', 'a'), ('f', 'b'), ('f', 'c'), ('f', 'd'), ('f', 'e'), ('f', 'f')]

Python permutations of both sequence and subsequences

Question: How do I implement double_permutations(s) below?
>>> s = [('a', 'b'), ('c', 'd'), ('e', 'f')]
>>> for answer in double_permutation(s):
... print(answer) # in some order
[('a', 'b'), ('c', 'd'), ('e', 'f')]
[('a', 'b'), ('d', 'c'), ('e', 'f')]
[('a', 'b'), ('c', 'd'), ('f', 'e')]
[('a', 'b'), ('d', 'c'), ('f', 'e')]
[('a', 'b'), ('e', 'f'), ('c', 'd')]
[('a', 'b'), ('f', 'e'), ('c', 'd')]
[('a', 'b'), ('e', 'f'), ('d', 'c')]
[('a', 'b'), ('f', 'e'), ('d', 'c')]
What I've tried (breaks down once the outer list is longer than 3 elements)
from itertools import permutations
def double_permutation(l):
def double_permutation_recur(s, r):
if not r:
yield s
else:
for permutation in permutations(r):
s1 = s + [permutation[0]]
s2 = s + [(permutation[0][1], permutation[0][0])]
for perm1 in double_permutation_recur(s1, permutation[1:]):
yield perm1
for perm2 in double_permutation_recur(s2, permutation[1:]):
yield perm2
return double_permutation_recur([l[0]], l[1:])
This should yield double_factorial(n-1) answers for a list of length n. This works up through n = 3, but breaks down at n = 4 (which yields 96 instead of 48 answers).
You can build this up from the primitives in the itertools module
import itertools
s = [('a', 'b'), ('c', 'd'), ('e', 'f')]
Is this what you're describing?
def permute(it):
return itertools.product(*(itertools.permutations(i) for i in it))
>>> for i in permute(s):
... print i
(('a', 'b'), ('c', 'd'), ('e', 'f'))
(('a', 'b'), ('c', 'd'), ('f', 'e'))
(('a', 'b'), ('d', 'c'), ('e', 'f'))
(('a', 'b'), ('d', 'c'), ('f', 'e'))
(('b', 'a'), ('c', 'd'), ('e', 'f'))
(('b', 'a'), ('c', 'd'), ('f', 'e'))
(('b', 'a'), ('d', 'c'), ('e', 'f'))
(('b', 'a'), ('d', 'c'), ('f', 'e'))
Or do you want:
def permute2(it):
return itertools.chain.from_iterable(
permute(p)
for p in itertools.permutations(it)
)
>>> for i in permute2(s):
... print i
(('a', 'b'), ('c', 'd'), ('e', 'f'))
(('a', 'b'), ('c', 'd'), ('f', 'e'))
(('a', 'b'), ('d', 'c'), ('e', 'f'))
(('a', 'b'), ('d', 'c'), ('f', 'e'))
(('b', 'a'), ('c', 'd'), ('e', 'f'))
(('b', 'a'), ('c', 'd'), ('f', 'e'))
(('b', 'a'), ('d', 'c'), ('e', 'f'))
(('b', 'a'), ('d', 'c'), ('f', 'e'))
(('a', 'b'), ('e', 'f'), ('c', 'd'))
(('a', 'b'), ('e', 'f'), ('d', 'c'))
(('a', 'b'), ('f', 'e'), ('c', 'd'))
(('a', 'b'), ('f', 'e'), ('d', 'c'))
(('b', 'a'), ('e', 'f'), ('c', 'd'))
(('b', 'a'), ('e', 'f'), ('d', 'c'))
(('b', 'a'), ('f', 'e'), ('c', 'd'))
(('b', 'a'), ('f', 'e'), ('d', 'c'))
(('c', 'd'), ('a', 'b'), ('e', 'f'))
(('c', 'd'), ('a', 'b'), ('f', 'e'))
(('c', 'd'), ('b', 'a'), ('e', 'f'))
(('c', 'd'), ('b', 'a'), ('f', 'e'))
(('d', 'c'), ('a', 'b'), ('e', 'f'))
(('d', 'c'), ('a', 'b'), ('f', 'e'))
(('d', 'c'), ('b', 'a'), ('e', 'f'))
(('d', 'c'), ('b', 'a'), ('f', 'e'))
(('c', 'd'), ('e', 'f'), ('a', 'b'))
(('c', 'd'), ('e', 'f'), ('b', 'a'))
(('c', 'd'), ('f', 'e'), ('a', 'b'))
(('c', 'd'), ('f', 'e'), ('b', 'a'))
(('d', 'c'), ('e', 'f'), ('a', 'b'))
(('d', 'c'), ('e', 'f'), ('b', 'a'))
(('d', 'c'), ('f', 'e'), ('a', 'b'))
(('d', 'c'), ('f', 'e'), ('b', 'a'))
(('e', 'f'), ('a', 'b'), ('c', 'd'))
(('e', 'f'), ('a', 'b'), ('d', 'c'))
(('e', 'f'), ('b', 'a'), ('c', 'd'))
(('e', 'f'), ('b', 'a'), ('d', 'c'))
(('f', 'e'), ('a', 'b'), ('c', 'd'))
(('f', 'e'), ('a', 'b'), ('d', 'c'))
(('f', 'e'), ('b', 'a'), ('c', 'd'))
(('f', 'e'), ('b', 'a'), ('d', 'c'))
(('e', 'f'), ('c', 'd'), ('a', 'b'))
(('e', 'f'), ('c', 'd'), ('b', 'a'))
(('e', 'f'), ('d', 'c'), ('a', 'b'))
(('e', 'f'), ('d', 'c'), ('b', 'a'))
(('f', 'e'), ('c', 'd'), ('a', 'b'))
(('f', 'e'), ('c', 'd'), ('b', 'a'))
(('f', 'e'), ('d', 'c'), ('a', 'b'))
(('f', 'e'), ('d', 'c'), ('b', 'a'))
Or to "anchor" the first element:
def permute3(s):
return s[:1] + list(p) for p in permute2(s[1:])
>>> for i in permute3(s):
... print i
[('a', 'b'), ('c', 'd'), ('e', 'f')]
[('a', 'b'), ('c', 'd'), ('f', 'e')]
[('a', 'b'), ('d', 'c'), ('e', 'f')]
[('a', 'b'), ('d', 'c'), ('f', 'e')]
[('a', 'b'), ('e', 'f'), ('c', 'd')]
[('a', 'b'), ('e', 'f'), ('d', 'c')]
[('a', 'b'), ('f', 'e'), ('c', 'd')]
[('a', 'b'), ('f', 'e'), ('d', 'c')]

Categories

Resources