I have the following problem: From a list of strings, i have to take the first letters from all the strings, after (from back to front), i have to take the second letters, after the third letters from front to end and so on.
Example input:
['abcd', 'efgh', 'ijkl', 'mnop']
Output should be:
'aeimnjfbcgkoplhd'
Here I am so far, the first "for" is appending to the array: aeim and cgko the second "for" is appending to the array: njfb and plhd. Anyway the order is not good, i need aeim + njfb + cgko + plhd
array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
for j in range(len(list_of_strings[0]/2)): # range(2) in our example
for i in range(len(list_of_strings)): # range(4) in our example
array.append(list_of_strings[i][j*2])
for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
array.append(list_of_strings[i][j])
Please help.
Thank you
You can use a simple one-liner using "unzip" (ie zip(*a)
) and str.join
:
a = ['abcd', 'efgh', 'ijkl', 'mnop']
b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
assert b == 'aeimnjfbcgkoplhd'
join
can take a generator expression as an argument, in this case the generator expression is
''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))
The expression
zip(*a)
unzips the strings in a
, ie it returns a generator which yields tuples containing all first letters, all second letters, etc. of each string.
The indexing in
t[::1-2*(i%2)]
ensures that we reverse the order of the tuple every 2nd iteration.
I benchmarked my one-liner vs. @cs95's answer , and performance of both is the same within error margins. I think in "real code" I'd hence prefer his solution for its higher clarity.
Think of the characters as elements in a 2D array:
a b c d
e f g h
i j k l
m n o p
We want to go in down on odd columns, then up on even columns, so we do something like this:
chars = []
for i in range(len(l[0])):
for w in l[::1 if i % 2 == 0 else -1]:
chars.append(w[i])
print(''.join(chars))
# aeimnjfbcgkoplhd
l[::1 if i % 2 == 0 else -1]
will reverse the list for even columns so we're picking characters from the end. This is intuitive but ugly since slicing the list creates a shallow copy. We can do something a little more clever by using a mod to determine whether to iterate in reverse:
chars = []
for i in range(len(l[0])):
for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
chars.append(l[j][i])
print(''.join(chars))
# aeimnjfbcgkoplhd
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.