Permutations and removing tuples - python

Here's my code:
import itertools
def permutations(string):
if len(string) <= 1:
return string
return itertools.permutations(string)
If 'ab' is input, it returns [('a', 'b'), ('b', 'a')]
Is there any way I can combine the tuple items and then change the tuple into a list item such that it returns: ['ab', 'ba']?

strings are seen as iterables, and combined into tuples by itertools.permutations.
To convert them back as strings, just use str.join on the tuples (would work on a longer permutation):
["".join(x) for x in [('a', 'b'), ('b', 'a')]]
in your case:
["".join(x) for x in itertools.permutations(string)]

[a+b for a,b in itertools.permutations(string)]

with map:
map(lambda(x):''.join(x), itertools.permutations(string))

Related

How to extract tuples from sublists?

I have tried many ways to solve this but instead of getting the tuples, I get individual elements like
'[' , '(' ,'a'.
My input:[[('a','b')],[('b','c'),('d','e')]]
Required output:('a','b')
('b','c')('d','e')
Is there any method to solve this?
You can try unpacking:
>>> inp = [[('a','b')],[('b','c'),('d','e')]]
>>> for inner_list in inp:
... print(*inner_list, sep='')
('a', 'b')
('b', 'c')('d', 'e')
with list comprenhension indexing two times.
out = [tup for l in myList for tup in l]
you get:
[('a', 'b'), ('b', 'c'), ('d', 'e')]
if you want to print each tupla individually just:
for i in out: print(i)

Convert list of tuples such that [(a,b,c)] converts to [(a,b),(a,c)]

Thoughts on how I would do this? I want the first value in the tuple to pair with each successive value. This way each resulting tuple would be a pair starting with the first value.
I need to do this: [(a,b,c)] --> [(a,b),(a,c)]
You can try this.
(t,)=[('a','b','c')]
[(t[0],i) for i in t[1:]]
# [('a', 'b'), ('a', 'c')]
Using itertools.product
it=iter(('a','b','c'))
list(itertools.product(next(it),it))
# [('a', 'b'), ('a', 'c')]
Using itertools.repeat
it=iter(('a','b','c'))
list(zip(itertools.repeat(next(it)),it))
# [('a', 'b'), ('a', 'c')]
a = [('a','b','c')]
a = a[0]
a = [tuple([a[0], a[index]]) for index in range(1, len(a))]
Try this !
A solution that uses itertools's combinations module.
from itertools import combinations
arr = (['a','b','c'])
for i in list(combinations(arr, 2)):
if(i[0]==arr[0]):
print(i ,end = " ")
This would give a solution ('a', 'b') ('a', 'c')
You can just append pairs of tuples to a list:
original = [(1,2,3)]
def makePairs(lis):
ret = []
for t in lis:
ret.append((t[0],t[1]))
ret.append((t[0],t[2]))
return ret
print(makePairs(original))
Output:
[(1, 2), (1, 3)]
If your tuples are arbitrary length you can write a simple generator:
def make_pairs(iterable):
iterator = iter(iterable)
first = next(iterator)
for item in iterator:
yield first, item
example result:
my_tuple = ('a', 'b', 'c', 'd')
list(make_pairs(my_tuple))
Out[170]: [('a', 'b'), ('a', 'c'), ('a', 'd')]
This is a memory-efficient solution.

Cleanest way to iterate over pair of iterables of different lengths, wrapping the shorter iterable? [duplicate]

This question already has answers here:
How to zip two differently sized lists, repeating the shorter list?
(15 answers)
Closed 5 years ago.
If I have two iterables of different lengths, how can I most cleanly pair them, re-using values from the shorter one until all values from the longer are consumed?
For example, given two lists
l1 = ['a', 'b', 'c']
l2 = ['x', 'y']
It would be desirable to have a function fn() resulting in pairs:
>>> fn(l1, l2)
[('a', 'x'), ('b', 'y'), ('c', 'x')]
I found I could write a function to perform this as such
def fn(l1, l2):
if len(l1) > len(l2):
return [(v, l2[i % len(l2)]) for i, v in enumerate(l1)]
return [(l1[i % len(l1)], v) for i, v in enumerate(l2)]
>>> fn(l1, l2)
[('a', 'x'), ('b', 'y'), ('c', 'x')]
>>> l2 = ['x', 'y', 'z', 'w']
>>> fn(l1,l2)
[('a', 'x'), ('b', 'y'), ('c', 'z'), ('a', 'w')]
However, I'm greedy and was curious what other methods exist? so that I may select the most obvious and elegant and be wary of others.
itertools.zip_longest as suggested in many similar questions is very close to my desired use case as it has a fillvalue argument which will pad the longer pairs. However, this only takes a single value, instead of wrapping back to the first value in the shorter list.
As a note: in my use case one list will always be much shorter than the other and this may allow a short-cut, but a generic solution would be exciting too!
You may use itertools.cycle() with zip to get the desired behavior.
As the itertools.cycle() document says, it:
Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy.
For example:
>>> l1 = ['a', 'b', 'c']
>>> l2 = ['x', 'y']
>>> from itertools import cycle
>>> zip(l1, cycle(l2))
[('a', 'x'), ('b', 'y'), ('c', 'x')]
Since in your case, length of l1 and l2 could vary, your generic fn() should be like:
from itertools import cycle
def fn(l1, l2):
return zip(l1, cycle(l2)) if len(l1) > len(l2) else zip(cycle(l1), l2)
Sample Run:
>>> l1 = ['a', 'b', 'c']
>>> l2 = ['x', 'y']
# when second parameter is shorter
>>> fn(l1, l2)
[('a', 'x'), ('b', 'y'), ('c', 'x')]
# when first parameter is shorter
>>> fn(l2, l1)
[('x', 'a'), ('y', 'b'), ('x', 'c')]
If you're not sure which one is the shortest, next it.cycle the longest len of the two lists:
def fn(l1, l2):
return (next(zip(itertools.cycle(l1), itertoools.cycle(l2))) for _ in range(max((len(l1), len(l2)))))
>>> list(fn(l1, l2))
[('a', 'x'), ('a', 'x'), ('a', 'x')]
itertools.cycle will repeat the list infinitely. Then, zip the two infinite lists together to get the cycle that you want, but repeated infinitely. So now, we need to trim it to the right size. max((len(l1), len(l2))) will find the longest length of the two lists, then next the infinite iterable until you get to the right length. Note that this returns a generator, so to get the output you want use list to eat the function.

combinations of letters using itertools in python2.7

I am trying to use itertools.combinations to return all the combinations of letters in alphabet with length at most n.
def string_combinations(alphabet, n):
'''
Parameters
----------
alphabet : {str}
n : {int}
Returns
-------
list : {list} of {str}
Example
-------
>>> string_combinations('abc', 2)
['a', 'b', 'c', 'ab', 'ac', 'bc']
'''
So far I have
return [str(x) for i in range(1,n+1) for x in itertools.combinations(alphabet,i)]
but itertools.combinations returns tuples in a list [('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'c')] How should I achieve my desired solution?
You can concatenate all the strings returned by itertools:
result = map("".join, (comb for i in range(1, n+1) for comb in itertools.combinations(alphabet, i)))
This is equivalent to putting a call to "".join inside a list comprehension:
result = ["".join(comb) for ...]
"".join(iterable) concatenates all the string that are retrieved from an iterable:
"".join(('a', 'b', 'c')) == "abc"

Converting a list of tuple of 2+ elements to a dictionary

I have a list of tuples which have more that 2 elements where the first element of each tuple is a number which is unique across all the tuples. How can I convert that list of tuples into a dictionary where a key is the 1st element of each tuple?
I know I can use dict(mylist) but it works only for 2-element tuples.
Use CoryKramer's answer if you are using Python 2, avoid the explicit indexing in favor of Extended Iterable Unpacking if you are using Python 3.
>>> lst = [(1, 'a', 'b'), (2, 'c', 'd')]
>>> {key:tuple(rest) for key, *rest in lst}
{1: ('a', 'b'), 2: ('c', 'd')}
You can use a dict comprehension
>>> l = [(1, 'a', 'b'),
(2, 'c', 'd')]
>>> {i[0]: i[1:] for i in l}
{1: ('a', 'b'),
2: ('c', 'd')}

Categories

Resources