What is the difference between these two List in Python? - python

I have two Lists in my program list1 and list2 which looks like the following:
list1 = ['ABC',
'ABD',
'ABE',
'ABF',
'ABG',
'ABH',
'ABI',
...]
list2 = [('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'B', 'E'),
('A', 'B', 'F'),
('A', 'B', 'G'),
('A', 'B', 'I'),
...]
Both the Lists are 2D because they return the same result on the same operation.
list1[0][1] returns 'B'
list2[0][1] also returns 'B'
What is the difference between list1 and list2 if they return the same result? How do I convert list2 in the format of list1?
Thank you.

The first list is list of strings and second list is list of tuples containing strings.
To convert list2 to list1 you can use:
list2 = [('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'B', 'E'),
('A', 'B', 'F'),
('A', 'B', 'G'),
('A', 'B', 'I'),]
new_list = [''.join(v) for v in list2]
print(new_list)
Output:
['ABC', 'ABD', 'ABE', 'ABF', 'ABG', 'ABI']

Related

How can I rearrange a set of values into new pattern on python and print results

so I will do my best to explain what I'm looking for,
at the moment I have a 100 item list that I want to repetitively shuffle using a set pattern to first check if the pattern will eventually bring me back to where I began
and 2 to print the result of each loop to a text file.
so using a 3 item list as my example
[a,b,c]
and the shuffle pattern [3 1 2]
where the 3rd item becomes the first.
the first item becomes the second
and the second item becomes the 3rd
on a loop would generate the following patterns
[a,b,c]
[3,1,2]
[c,a,b]
[b,c,a]
[a,b,c]
but I have a list at the moment of 100 items that I need to find every single arrangement for a few different patterns I would like to test out.
does anyone know of a way to do this in python please.
You can define function and call this function multi times like below:
>>> def func(lst, ptr):
... return [lst[idx-1] for idx in ptr]
>>> lst = ['a','b','c']
>>> ptr = [3,1,2]
>>> for _ in range(5):
... lst = func(lst, ptr)
... print(lst)
['c', 'a', 'b']
['b', 'c', 'a']
['a', 'b', 'c']
['c', 'a', 'b']
['b', 'c', 'a']
You could use numpy advanced integer indexing if your list contains a numeric type:
import numpy as np
original_list=[1,2,3]
numpy_array = np.array(original_list)
pattern = [2,1,0]
print(numpy_array[pattern])
>>> array([3, 2, 1])
def rearrange(pattern : list,L:list):
new_list = []
for i in pattern :
new_list.append(L[i-1])
return new_list
print(rearrange([3,1,2],['a','b','c']))
output :
['c', 'a', 'b']
Itertools could be what you need.
import itertools
p = itertools.permutations(['a','b','c', 'd'])
list(p)
Output:
[('a', 'b', 'c', 'd'),
('a', 'b', 'd', 'c'),
('a', 'c', 'b', 'd'),
('a', 'c', 'd', 'b'),
('a', 'd', 'b', 'c'),
('a', 'd', 'c', 'b'),
('b', 'a', 'c', 'd'),
('b', 'a', 'd', 'c'),
('b', 'c', 'a', 'd'),
('b', 'c', 'd', 'a'),
('b', 'd', 'a', 'c'),
('b', 'd', 'c', 'a'),
('c', 'a', 'b', 'd'),
('c', 'a', 'd', 'b'),
('c', 'b', 'a', 'd'),
('c', 'b', 'd', 'a'),
('c', 'd', 'a', 'b'),
('c', 'd', 'b', 'a'),
('d', 'a', 'b', 'c'),
('d', 'a', 'c', 'b'),
('d', 'b', 'a', 'c'),
('d', 'b', 'c', 'a'),
('d', 'c', 'a', 'b'),
('d', 'c', 'b', 'a')]
​

Python: 3rd level nested list comprehension not acting as expected

I am trying to get all possible permutations of length 1, 2 and 3 for the charactes "a", "b" and "c"
from itertools import permutations
a = ['a','b', 'c']
perm1 = permutations(a, 1)
perm2 = permutations(a, 2)
perm3 = permutations(a, 3)
p_list = []
p_list.extend(list(perm1))
p_list.extend(list(perm2))
p_list.extend(list(perm3))
str = [[j for j in i] for i in p_list]
print(str[3])
At this point things are expected
When I modify the str = line to this str = [[[''.join(k) for k in j] for j in i] for i in p_list] I would expect to get a list of strings where each permutation is a string with no commas. e.g. ["abc", "a", "b", "c"] etc. but instead I get a list of lists.
First thing: please don't set str as variable.
Below I copied your code, commenting what p_list looks like.
from itertools import permutations
a = ['a','b', 'c']
perm1 = permutations(a, 1)
perm2 = permutations(a, 2)
perm3 = permutations(a, 3)
p_list = []
p_list.extend(list(perm1))
p_list.extend(list(perm2))
p_list.extend(list(perm3))
# p_list = [('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('a', 'b', 'c'), ('a', 'c', 'b'), ('b', 'a', 'c'), ('b', 'c', 'a'), ('c', 'a', 'b'), ('c', 'b', 'a')]
As you can see, your data structure is not 3rd level: it is only a list of tuples. Now I think it becomes clear that your list comprehension is just iterating over each element inside the tuples, not joining them like:
result = [''.join(n) for n in p_list]
# result = ['a', 'b', 'c', 'ab', 'ac', 'ba', 'bc', 'ca', 'cb', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba']

Generating combinations follow by each element

I have a list of chars chrs = ['A','B','C','D']. How can I generate the outputs like this ['A','AB','ABC','ABCD','B','BC','BCD','C','CD','D'] in python?
Thank you so much!
Try this
s = ''.join(chrs)
res = [s[i: j+1] for i in range(len(s)) for j in range(i, len(s))]
print(res)
Output:
['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']
A one liner is to use function powerset() from package more_itertools.
Like the following:
from more_itertools import powerset
l = ['A','B','C','D']
list(powerset(l))
# [(), ('A',), ('B',), ('C',), ('D',), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D'), ('A', 'B', 'C', 'D')]
Then you can join it to strings, and sort to get the desired output.
ll = ["".join(x) for x in list(powerset(l))]
sorted(ll)
# ['', 'A', 'AB', 'ABC', 'ABCD', 'ABD', 'AC', 'ACD', 'AD', 'B', 'BC', 'BCD', 'BD', 'C', 'CD', 'D']
You can also easily get read from the empty string by ll[1:]
chrs = ['A','B','C','D']
all_combinations = []
for current_start_index in range(len(chrs)):
for current_combinations_lengh in range(current_start_index, len(chrs)):
all_combinations.append(''.join(list(chrs[current_start_index:current_combinations_lengh+1])))
# Sort, if neccesary
# all_combinations.sort()
# ['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D']
print(all_combinations)
A simple solution without using any package or module and with basic idea:
chrs=['a','b','c','d']
chrs=''.join(chrs)
a2=[]
i=0
j=1
while(i<len(a) and j<len(a)):
a2.append(a[i:j+1])
j+=1
if j>=len(a):
i+=1
j+=i
a2.append(chrs[-1])
print(a2)

How to simplify this code about iteration combination in python

So i have this code below that i created. This code will list every possible combination of a certain value, in this example is "a" "b" "c" "d". If i use this code, the result would be like this: a, aa, ab, ac, ad, aaa, aab, aac, aad, aba, abb, abc, etc. How to simplify this for loop code, so that i can input more values without createing more for loop?
n = "abcd"
for c in n:
print(c)
for c1 in n:
print(c+c1)
for c2 in n:
print(c+c1+c2)
for c3 in n:
print(c+c1+c2+c3)
https://docs.python.org/2/library/itertools.html
Itertools permutations and combinations is what you're after.
itertools.permutations([1, 2, 3])
from itertools import combinations
n = "abcd"
print ([''.join(l) for i in range(len(n)) for l in combinations(n, i+1)])
output:
['a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'bc', 'bd', 'cd', 'abc', 'abd', 'acd', 'bcd', 'abcd']
edit:
from itertools import combinations_with_replacement
n = "abcd"
comb = []
for i in range(1, len(n)+1):
comb += list(combinations_with_replacement(n, i))
print([''.join(c) for c in comb])
output:
['a', 'b', 'c', 'd', 'aa', 'ab', 'ac', 'ad', 'bb', 'bc', 'bd', 'cc', 'cd', 'dd', 'aaa', 'aab', 'aac', 'aad', 'abb', 'abc', 'abd', 'acc', 'acd', 'add', 'bbb', 'bbc', 'bbd', 'bcc', 'bcd', 'bdd', 'ccc', 'ccd', 'cdd', 'ddd', 'aaaa', 'aaab', 'aaac', 'aaad', 'aabb', 'aabc', 'aabd', 'aacc', 'aacd', 'aadd', 'abbb', 'abbc', 'abbd', 'abcc', 'abcd', 'abdd', 'accc', 'accd', 'acdd', 'addd', 'bbbb', 'bbbc', 'bbbd', 'bbcc', 'bbcd', 'bbdd', 'bccc', 'bccd', 'bcdd', 'bddd', 'cccc', 'cccd', 'ccdd', 'cddd', 'dddd']
To get the same result of 340 elements you can use itertools.product:
product(n, repeat=1)
product(n, repeat=2)
...
product(n, repeat=4)
To print the result you can use the following loop:
from itertools import product
n = "abcd"
for i in range(1, 5):
for prod in product(n, repeat=i):
print(''.join(prod))
To get an extra level you can easily increase the 5 in range. Note: the order of printing is slightly different than in your code.
You can use itertools module to solve your problem. You need combinations_with_replacement function with all possible lengths:
import itertools as it
n = "abcd"
result = []
for l in range(len(n)):
result += list(it.combinations_with_replacement(n, l+1))
print(result)
[('a',), ('b',), ('c',), ('d',), ('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('c', 'c'), ('c', 'd'), ('d', 'd'), ('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c'), ('a', 'a', 'd'), ('a', 'b', 'b'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'c'), ('a', 'c', 'd'), ('a', 'd', 'd'), ('b', 'b', 'b'), ('b', 'b', 'c'), ('b', 'b', 'd'), ('b', 'c', 'c'), ('b', 'c', 'd'), ('b', 'd', 'd'), ('c', 'c', 'c'), ('c', 'c', 'd'), ('c', 'd', 'd'), ('d', 'd', 'd')]

How to append elements from 2 short lists into another big list of tuples?

Say I have the following lists:
l1 = [('a','b','c'),('d','e','f'),('g','h','i'),('j','k','l')]
l2 = ['x','y','z']
l3 = ['m','n']
I want to extract elements from l2 and l3, then append l2[i](i in range(len(l2))) as the first element inside every tuple, and l3[i](i in range(len(l2))) as the last element inside every tuple.
so the result will look like the followings:
l1 = [('x','a','b','c','m'),('x','a','b','c','n'),('y','a','b','c','m'),('y','a','b','c','n'), ('z','a','b','c','m'),('z','a','b','c','n')]
and yes, the len of l1 will be increased.
You can do that with the help of itertools.chain.from_iterable and itertools.product, and get the cartesian product, like this
>>> from itertools import chain, product
>>> from pprint import pprint
>>> pprint([tuple(chain.from_iterable(i)) for i in product(l2, [l1[0]], l3)])
[('x', 'a', 'b', 'c', 'm'),
('x', 'a', 'b', 'c', 'n'),
('y', 'a', 'b', 'c', 'm'),
('y', 'a', 'b', 'c', 'n'),
('z', 'a', 'b', 'c', 'm'),
('z', 'a', 'b', 'c', 'n')]
You are finding the cartesian product between l2, the first element of l1 and l3. Since the result will be a tuple with the element from l2 (a string) and the first element of l1 (a tuple) and an element from l3 (a string), we flatten it with chain.from_iterable.
Let's say we don't flatten the tuples, then this is what you will get
>>> pprint([tuple(items) for items in product(l2, [l1[0]], l3)])
[('x', ('a', 'b', 'c'), 'm'),
('x', ('a', 'b', 'c'), 'n'),
('y', ('a', 'b', 'c'), 'm'),
('y', ('a', 'b', 'c'), 'n'),
('z', ('a', 'b', 'c'), 'm'),
('z', ('a', 'b', 'c'), 'n')]
This is why we use chain.from_iterable and flatten the tuples.
What about playing with zip and list comprehension :
>>> [zip(*i) for i in zip(zip(l2,l2),zip(l1,l1),(l3 for _ in range(2*len(l1))))]
[[('x', ('a', 'b', 'c'), 'm'), ('x', ('a', 'b', 'c'), 'n')], [('y', ('d', 'e', 'f'), 'm'), ('y', ('d', 'e', 'f'), 'n')], [('z', ('g', 'h', 'i'), 'm'), ('z', ('g', 'h', 'i'), 'n')]]

Categories