Duplicate every value in array as a new array - python

I have an numpy ndarray input like this
[[T, T, T, F],
[F, F, T, F]]
and I want to duplicate every value as a new array, so the output would be
[[[T,T], [T,T], [T,T], [F,F]]
[[F,F], [F,F], [T,T], [F,F]]]
How can I do this? Thank you in advance

One way would be using np.dstack to replicate the array along the third axis:
np.dstack([a, a])
array([[['T', 'T'],
['T', 'T'],
['T', 'T'],
['F', 'F']],
[['F', 'F'],
['F', 'F'],
['T', 'T'],
['F', 'F']]], dtype='<U1')
Setup:
T = 'T'
F = 'F'
a = np.array([[T, T, T, F],
[F, F, T, F] ])

you can just use list comprehension:
data =[['T', 'T', 'T', 'F'],
['F', 'F', 'T', 'F'] ]
d = [[[i]*2 for i in j] for j in data]
print (d)
output:
[[['T', 'T'], ['T', 'T'], ['T', 'T'], ['F', 'F']], [['F', 'F'], ['F', 'F'], ['T', 'T'], ['F', 'F']]]

Related

How to split a nested list into multiple nested lists?

I have a nested list shaped like
mylist = [[a, b, c, d], [e, f, g, h], [i, j, k, l]]
And i need to split the nested lists so that every two items are grouped together like this:
Nested_list = [[[a, b], [c, d], [[e, f], [g, h]], [[i, j], [k, l]]
I tried splitting them by them by usinga for loop that appended them but this doesn't work.
mylist = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
nested_list = [ [i[:2], i[2:]] for i in mylist ]
print(nested_list)
Output:
[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']], [['i', 'j'], ['k', 'l']]]
mylist = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]
Nested_list = []
for x in mylist:
Nested_list.append(x[:2])
Nested_list.append(x[2:])
print(Nested_list)
Output: [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h'], ['i', 'j'], ['k', 'l']]
import numpy as np
Nested_list = np.array(mylist).reshape(-1,2,2)
output:
array([[['a', 'b'],
['c', 'd']],
[['e', 'f'],
['g', 'h']],
[['i', 'j'],
['k', 'l']]], dtype='<U1')
from itertools import *
my_list = chain.from_iterable(my_list)
def grouper(inputs, n):
iters = [iter(inputs)] * n
return zip_longest(*iters)
print(list(grouper(my_list, 2)))

compare list of lists and create clusters

I have a list that has 10,000 lists of strings of different lengths. For this question, I will make it simple and give an example of only a list that has 10 lists as follows.
list = [['a','w','r', 't'], ['e','r', 't', 't', 'r', 'd', 's'], ['a','w','r', 't'], ['n', 'g', 'd', 'e', 's'], ['a', 'b', 'c'], ['t', 'f', 'h', 'd', 'p'], ['a', 'b', 'c'], ['a','w','r', 't'], ['s','c','d'], ['e','r', 't', 't', 'r', 'd', 's']]
what I want is to compare each list with all other lists and group the similar lists into one new list (called a cluster) and also group the list indices.
Expected output:
cluster_1_lists = [['a','w','r', 't'], ['a','w','r', 't'], ['a','w','r', 't']]
cluster_1_indices = [0,2,7]
cluster_2_lists = [['e','r', 't', 't', 'r', 'd', 's'],['e','r', 't', 't', 'r', 'd', 's']]
cluster_2_indices = [1,9]
cluster_3_lists = [['n', 'g', 'd', 'e', 's']]
cluster_3_indices = [3]
cluster_4_lists = [['a', 'b', 'c'], ['a', 'b', 'c']]
cluster_4_indices = [4,6]
cluster_5_lists = [['t', 'f', 'h', 'd', 'p']]
cluster_5_indices = [5]
cluster_6_lists = [['s','c','d']]
cluster_6_indices = [8]
Can you help me to implement this in python?
Ok so here, I'll basically be using a dictionary to make a cluster. Here's what I've done:
list= [['a','w','r', 't'], ['e','r', 't', 't', 'r', 'd', 's'], ['a','w','r', 't'], ['n', 'g', 'd', 'e', 's'], ['a', 'b', 'c'], ['t', 'f', 'h', 'd', 'p'], ['a', 'b', 'c'], ['a','w','r', 't'], ['s','c','d'], ['e','r', 't', 't', 'r', 'd', 's']]
cluster = {}
for i in list:
cluster[''.join(i)] = []
cluster[''.join(i)+'_indices'] = []
for j in range(len(list)-1):
for k in cluster:
if ''.join(list[j]) == k:
cluster[k].append(list[j])
cluster[k+'_indices'].append(j)
print(cluster)
The first for loop basically creates a key with the joint name of your list, because you cannot have a key as a list. Then, it stores it val as an empty list which will further be appended. In the second for loop, it iterates again through the list and inside it I have iterated through the keys in the cluster (dict). Then, it basically checks if the joint list is equal to the key name, if yes it appends the value. The output will look like this:
Output: {'awrt': [['a', 'w', 'r', 't'], ['a', 'w', 'r', 't'], ['a', 'w', 'r', 't']], 'awrt_indices': [0, 2, 7], 'erttrds': [['e', 'r', 't', 't', 'r', 'd', 's']], 'erttrds_indices': [1], 'ngdes': [['n', 'g', 'd', 'e', 's']], 'ngdes_indices': [3], 'abc': [['a', 'b', 'c'], ['a', 'b', 'c']], 'abc_indices': [4, 6], 'tfhdp': [['t', 'f', 'h', 'd', 'p']], 'tfhdp_indices': [5], 'scd': [['s', 'c', 'd']], 'scd_indices': [8]}
Note: Creating separate variables as you want will just make the code messy, python has a solution to it which is dictionaries and thus I've used it.
Here is the working answer:
for i in list:
cluster[''.join(i)] = []
xx = []
xx_idx=[]
for k in cluster:
yy = []
yy_ixd = []
for j in range(len(list)):
if k == ''.join(list[j]):
yy.append(list[j])
yy_ixd.append(j)
xx.append(yy)
xx_idx.append(yy_ixd)
print("output", xx)
print("indices: ", xx_idx)
Output:
output [[['a', 'w', 'r', 't'], ['a', 'w', 'r', 't'], ['a', 'w', 'r', 't']], [['e', 'r', 't', 't', 'r', 'd', 's'], ['e', 'r', 't', 't', 'r', 'd', 's']], [['n', 'g', 'd', 'e', 's']], [['a', 'b', 'c'], ['a', 'b', 'c']], [['t', 'f', 'h', 'd', 'p']], [['s', 'c', 'd']]]
indices: [[0, 2, 7], [1, 9], [3], [4, 6], [5], [8]]

return list pair (print out) from 2 list of same length

I have 2 lists (x and y) and I want to output in x, y (just the print out). May I know how to do it? Do I need a loop to loop through each item in the x and y list?
input :
x = [['A', 'B'], ['C', 'D'], ['F', 'G']]
y = [['L', 'M'], ['J', 'K'], ['O', 'P', 'Q']]
output :
x, y format
['A', 'B'] ['L', 'M']
['C', 'D'] ['J', 'K']
['F', 'G'] ['O', 'P', 'Q']
The closest I got is as below :
for row in x:
n = []
for loop in y :
for x in loop :
n.append(x)
print(' '.join(row).strip().split()) , n
Output :
['A', 'B'] ['L', 'M']
['A', 'B'] ['L', 'M', 'J', 'K']
['A', 'B'] ['L', 'M', 'J', 'K', 'O', 'P', 'Q']
['C', 'D'] ['L', 'M']
['C', 'D'] ['L', 'M', 'J', 'K']
['C', 'D'] ['L', 'M', 'J', 'K', 'O', 'P', 'Q']
['F', 'G'] ['L', 'M']
['F', 'G'] ['L', 'M', 'J', 'K']
['F', 'G'] ['L', 'M', 'J', 'K', 'O', 'P', 'Q']
You can use zip to make tuples of elements of your lists:
list(zip(x, y))
Produces:
[(['A', 'B'], ['L', 'M']),
(['C', 'D'], ['J', 'K']),
(['F', 'G'], ['O', 'P', 'Q'])]
The resulting list is, in this example, of length 3. The first element is:
>>> list(zip(x, y))[0]
(['A', 'B'], ['L', 'M'])
In order to print the tuples with a space in between:
for a, b in zip(x, y):
print(f'{a} {b}')
Output:
['A', 'B'] ['L', 'M']
['C', 'D'] ['J', 'K']
['F', 'G'] ['O', 'P', 'Q']

Split lists into chunk based of index of another list

I want to split a list into chunks using values of of another list as the range to split.
indices = [3, 5, 9, 13, 18]
my_list = ['a', 'b', 'c', ..., 'x', 'y', 'z']
So basically, split my_list from range:
my_list[:3], mylist[3:5], my_list[5:9], my_list[9:13], my_list[13:18], my_list[18:]
I have tried to indices into chunks of 2 but the result is not what i need.
[indices[i:i + 2] for i in range(0, len(indices), 2)]
My actual list length is 1000.
You could also do it using simple python.
Data
indices = [3, 5, 9, 13, 18]
my_list = list('abcdefghijklmnopqrstuvwxyz')
Solution
Use list comprehension.
[(my_list+[''])[slice(ix,iy)] for ix, iy in zip([0]+indices, indices+[-1])]
Output
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
Check if correct order of indices are extracted
dict(((ix,iy), (my_list+[''])[slice(ix,iy)]) for ix, iy in zip([0]+indices, indices+[-1]))
Output
{(0, 3): ['a', 'b', 'c'],
(3, 5): ['d', 'e'],
(5, 9): ['f', 'g', 'h', 'i'],
(9, 13): ['j', 'k', 'l', 'm'],
(13, 18): ['n', 'o', 'p', 'q', 'r'],
(18, -1): ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']}
Can use itertools.zip_longest
[my_list[a:b] for a,b in it.zip_longest([0]+indices, indices)]
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'x', 'y', 'z']]
A little bit of code golf for fun:
map(my_list.__getitem__, map(lambda s: slice(*s), it.zip_longest([0]+indices, indices)))
One way using itertools.tee and pairwise:
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
chunks = [my_list[i:j] for i, j in pairwise([0, *indices, len(my_list)])]
print(chunks)
Output:
[['a', 'b', 'c'],
['d', 'e'],
['f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm'],
['n', 'o', 'p', 'q', 'r'],
['s', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
If numpy is an option, use numpy.array_split, which is meant for this:
import numpy as np
np.array_split(my_list, indices)
Output:
[array(['a', 'b', 'c'], dtype='<U1'),
array(['d', 'e'], dtype='<U1'),
array(['f', 'g', 'h', 'i'], dtype='<U1'),
array(['j', 'k', 'l', 'm'], dtype='<U1'),
array(['n', 'o', 'p', 'q', 'r'], dtype='<U1'),
array(['s', 't', 'u', 'v', 'w', 'x', 'y', 'z'], dtype='<U1')]

Python: Iterating through the columns in a list of list to find the palindromes

Here I have a word list as:
[['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
And I have to display all the palindromes in this list which are in rows as well as columns.
I have coded to find all the palindromes in the rows. But cannot implement a method to find the palindromes in the columns.
Here is my code so far:
result_1=""
if len(palindrome)==len_line_str:
for row in range(len(palindrome)):
for horizontal_line in range(len(palindrome[row])):
if ''.join(palindrome[row])==''.join(reversed(palindrome[row])):
result_1=''.join(palindrome[row])+" is a palindrome starting at ["+str(row)+"]["+str(row)+"] and is a row in the table"
print(result_1)
Which will display the output:
rotor is a palindrome starting at [0][0] and is a row in the table
Where "rotor" is a palindrome.
I need a method to get the palindromes in the columns which are:
"refer", "tenet", "radar"
Any help is much appreciated. Thanks in advance!
You can use zip to transpose your lists:
>>> t = [['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
[['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
>>> list(zip(*t))
[('r', 'e', 'f', 'e', 'r'), ('o', 'v', 'i', 'n', 'a'), ('t', 'e', 'n', 'e', 't'), ('o', 'i', 'e', 't', 'e'), ('r', 'a', 'd', 'a', 'r')]
Your columns are now rows, and you can apply the same method than before. If you just need the words, you can use list comprehensions:
>>> rows = [['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
>>> [''.join(row) for row in rows if row[::-1] == row ]
['rotor']
>>> [''.join(column) for column in zip(*rows) if column[::-1] == column ]
['refer', 'tenet', 'radar']
This will do the job:
palindrome=[['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
n=len(palindrome)
for col in range(len(palindrome[0])):
col_word=[palindrome[i][col] for i in range(n)]
if ''.join(col_word)==''.join(reversed(col_word)):
result=''.join(col_word)+" is a palindrome starting at ["+str(col)+"] and is a col in the table"
print(result)
This prints
refer is a palindrome starting at [0] and is a col in the table
tenet is a palindrome starting at [2] and is a col in the table
radar is a palindrome starting at [4] and is a col in the table
Basically, in order to access the words in the column, you can do
col_word=[palindrome[i][col] for i in range(n)]
This fixes the column and iterates over the rows. The rest of the code is structures similarly to yours.
​
I saw you did not want to use Zip (which I would recommend using):
Alternative answer:
list_ = [['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
You can get the palindromes (rows) by checking each list with the reversed list [::-1]:
[i==i[::-1] for i in list_]
# prints [True, False, False, False, False]
And get the palindromes (columns) by 1. create the column list (called list_2 below) with a list comprehension and 2. same principle as above:
list_2 = [[i[ind] for i in list_] for ind in range(len(list_))]
[i==i[::-1] for i in list_2]
# prints [True, False, True, False, True]
Update
If you want the answers directly you can do:
[i for i in list_ if i==i[::-1]]
# prints [['r', 'o', 't', 'o', 'r']]
# and list_2: [['r', 'e', 'f', 'e', 'r'],['t', 'e', 'n', 'e', 't'],['r', 'a', 'd', 'a', 'r']]
There are a lot of ways to do it. I will take as example your code because of your effort on it
Another alternative following your code, is creating the columns in another list and check wich of them are palindromes:
palindrome = [['r', 'o', 't', 'o', 'r'],
['e', 'v', 'e', 'i', 'a'],
['f', 'i', 'n', 'e', 'd'],
['e', 'n', 'e', 't', 'a'],
['r', 'a', 't', 'e', 'r']]
len_line_str = 5
result_1=""
def is_pal(string):
return string == reversed(string)
colums = []
if len(palindrome)==len_line_str:
for row in range(len(palindrome)):
vertical = []
if ''.join(palindrome[row])==''.join(reversed(palindrome[row])):
result_1+=''.join(palindrome[row])+" is a palindrome starting at ["+str(0)+"]["+str(row)+"] and is a row in the table. " + "\n"
for horizontal_line in range(len(palindrome[row])):
if(len_line_str-1 > horizontal_line):
vertical += [palindrome[horizontal_line][row]]
else:
vertical += [palindrome[horizontal_line][row]]
colums += [(vertical,row)]
for word in colums:
if ''.join(word[0])==''.join(reversed(word[0])):
result_1+=''.join(word[0])+" is a palindrome starting at ["+str(0)+"]["+str(word[1])+"] and is a column in the table" + "\n"
print(result_1)
This should work. First loop iterates through the list s and the second loop iterates through each list.
Assuming s is the name of the list- [['r', 'o', 't', 'o', 'r'], ['e', 'v', 'e', 'i', 'a'], ['f', 'i', 'n', 'e', 'd'], ['e', 'n', 'e', 't', 'a'], ['r', 'a', 't', 'e', 'r']]
for i in xrange(0,len(s),1):
str = ""
for j in s:
str = str + j[i]
print str
if str == str[::-1]:
print str," is a pallindrome - column", i
else:
print str," is not a pallindrome - column", i
There is no column wise traversal in Python. One hacky way you can follow is to perform transpose operation on your input matrix. Below is a simple way to implement transpose using list comprehensions.
def transpose(matrix):
if not matrix:
return []
return [[row[i] for row in matrix] for i in range(len(matrix[0]))]
Your same logic should work once modify your input using transpose.
Hope this helps!!

Categories