Python List content stripping - python

So, I have a list having string such as
matches=['A vs B','C vs D','E vs F','G vs H']
I want to get strip the list contents in such a way that I get two more lists of
t1=[A,C,E,G]
t2=[B,D,F,H]
I've tried strip function as
t1=[i.strip("vs")[0] for i in matches]
t2=[i.strip("vs")[-1] for i in matches]
But I'm not getting the desirable results. Can someone guide me trough it. Thanks

I would use :
t1, t2 = map(list, zip(*[m.split(" vs ") for m in matches]))
And since you have a pandas tag, here is any approach with split and the Series constructor :
t1, t2 = (
pd.Series(matches)
.str.split(" vs ", expand=True)
.values
.T.tolist()
)
Output :
print(t1)
#['A', 'C', 'E', 'G']
print(t2)
#['B', 'D', 'F', 'H']

Iterate over the matches list. Split each element on whitespace. Populate your lists.
matches=['A vs B','C vs D','E vs F','G vs H']
t1 = []
t2 = []
for match in matches:
a, _, b = match.split()
t1.append(a)
t2.append(b)
print(t1)
print(t2)
Output:
['A', 'C', 'E', 'G']
['B', 'D', 'F', 'H']

Related

Joining values of a list inside another list into a string

Im trying to join the letters as a string that's inside the list which is also inside the list. So for example, it looks like this [['a', 'b', 'c'], ['d', 'e', 'f']] however I want the result to look like 'ad be cf' which is basically taking the element that lies in the same position in the list. I know how to join the elements into a list that can look like 'abcdef', however, i don't know which I could add in order to return a string that looks like above.
Any advice would be thankful!
string = ''
new_grid = []
for a in grid:
for b in a:
string += b
return string
When you want to transpose lists into columns, you typically reach for zip(). For example:
l = [['a', 'b', 'c'], ['d', 'e', 'f']]
# make a list of columns
substrings = ["".join(sub) for sub in zip(*l)]
#['ad', 'be', 'cf']
print(" ".join(substrings))
# alternatively print(*substrings, sep=" ")
# ad be cf
This works:
my_list = [['a', 'b', 'c'], ['d', 'e', 'f']]
sorted_list = [list(pair) for pair in zip(my_list[0], my_list[1])]
for i in range(3):
string = ''.join(sorted_list[i])
print(string, end=" ")
First, we are pairing each individual list to its corresponding value using [zip][1], then we are joining it into a string, and printing it out.
This solution may not be the most efficient, but it's simple to understand.
Another quick solution without zip could look like this:
my_list = [['a', 'b', 'c'], ['d', 'e', 'f']]
sorted_list = list(map(lambda a, b: a + b, my_list[0], my_list[1]))
print(" ".join(sorted_list))

How would you re-order the reordered list back to its previous form?

element = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
index_list = [3,5,6,1,2,4,0]
result = [element[i] for i in index_list]
print(result)
this would eventually give me a ordered list based on the index list which would give
['d', 'f', 'g', 'b', 'c', 'e', 'a'].
How would you re-order this already re-ordered list back to its previous form which would be ['a', 'b', 'c', 'd', 'e', 'f', 'g']? I tried using the given index list again but it did not returned it back, but simply gave me a new list. Would there be any way I could still use the given index list to reorder the list back?
You can do the opposite:
reordered = [None] * len(result)
for index, e in zip(index_list, result):
reordered[index] = e
You can process index_list to do the reverse permutation:
index_list = [3,5,6,1,2,4,0]
reverse = [i for i, n in sorted(enumerate(index_list), key=lambda x: x[1])]
original = [result[i] for i in reverse]
something like this
print([a for a, b in sorted(zip(result, index_list), key=lambda x: x[1])])

Is there a better way to join elements from three lists than a triple nested for loop?

I have three lists like so:
l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l3 = ['h', 'i', 'j']
Now, what I am trying to do is combine all the elements that are in the same position on one line like so:
line_1: 'adh'
line_2: 'bei'
line_3: 'cfj'
is there a better way to do this than a triple nested for loop?
for i in range(len(l1)):
for j in range(len(l2)):
for k in range(len(l3)):
if i == j and j == k:
print(l1[i] + l2[j] + l3[k])
Basically I am trying to get something running faster than O(n^3) because I have about 100,000 items I would like to do this with.
Not sure if there would be a way with the CSV module to do this but after the combining each row is going to be written to a csv file. I have not found what I am looking for thus far and figured someone out in the community might know how to better approach this.
Wow thanks everyone who took a look at this!. There were a couple answers and they all worked. I am going to mark the question answered for whoever posted first. Thanks again to everyone who took a look! I did not even know about the zip function.
You probably want something like:
l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l3 = ['h', 'i', 'j']
for line in (''.join(t) for t in zip(l1, l2, l3)):
print(line)
How about this?
l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l3 = ['h', 'i', 'j']
for a,b,c in zip(l1, l2, l3):
print(a, b, c)
But even the pattern you went with works fine if you cut the redundant recursion:
for i in range(len(l1)):
print(l1[i], l2[i], l3[i])
Edit: as noted in the other answer, you have to join them up again afterwards ;)
You can use only one loop, assuming that all lists have the same length:
for i in range(len(l1)):
print(l1[i]+l2[i]+l3[i])
In one line, simplified by #juanpa.arrivillaga:
>>> list(map(''.join, zip(l1, l2, l3)))
['adh', 'bei', 'cfj']
OR, suggested by #2e0byo with a comprehension:
>>> ["".join(x) for x in zip(l1, l2, l3)]
['adh', 'bei', 'cfj']
The join() string method returns a string by joining all the elements of an iterable. So easily get your output from the below code,
l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l3 = ['h', 'i', 'j']
line1="".join(l1)
line2="".join(l2)
line3="".join(l3)
print(f"line1-{line1}")
print(f"line2-{line2}")
print(f"line3-{line3}")

python string operation. sticked words separation

I have a pretty challenging problem here I need your help.
the problem is this:
I have a string for example "abcde"
Now, I want to separate this string into any possible ordered combinations as a list of strings.
for example,
my_function('abcde')
output =
[
['a', 'b', 'c', 'd', 'e'],
['a', 'b', 'c', 'de'],
['a', 'b', 'cde'],
['a', 'bced'],
['a', 'b', 'cd', 'e'],
['a', 'bc', 'd', 'e'],
['a', 'bc', 'de'],
['a', 'bcd', 'e'],
['a', 'bcde'],
['ab', 'c', 'd', 'e'],
['ab', 'c', 'de'],
['ab', 'cd', 'e'],
['ab', 'cde'],
['abc','d','e'],
['abc', 'de'],
['abcd', 'e'],
['abcde']
]
It is not quite the permutation since the order matters.
Same result without itertools:
s = 'python'
splits = len(s) - 1
output = []
for i in range(2 ** splits):
combination = []
word = ''
for position in range(splits + 1):
word += s[position]
if not (i & (1 << position)):
combination.append(word)
word = ''
output.append(combination)
output.sort()
for combination in output:
print(combination)
Just for beginners.
You could do this:
import itertools
def get_slices(values):
slices_len = len(values) - 1
for is_slice in itertools.product([True, False], repeat=slices_len):
start_index = 0
slices = []
for slice_index, is_index_slice in enumerate(is_slice, 1):
if is_index_slice:
index_slice = values[start_index:slice_index]
start_index = slice_index
slices.append(index_slice)
slices.append(values[start_index:])
yield slices
Most important part of this code is the itertools.product call at the beginning, this generates all possible types of slices. A slice definition here corresponds to a bunch of bools representing whether two adjacent elements at all indices of pairs in values (there are slices_len of these) are joined or not.
list(get_slices("abcde)) will return the list you requested. If you don't need all results immediately, and instead want to iterate through them, you don't need the surrounding list call.
If you want the reverse order, you can switch the [True, False] with [False, True].
i got 16 items and you have 17 :-)
def fn(base_str):
result = [[base_str]]
for i in range(1, len(base_str)):
child = fn(base_str[i:])
for x in child:
x.insert(0, base_str[0:i])
result = child + result
return result
print(fn("abcde"))

Split list into list of lists by regex

I want to split a character list into a list of lists, where the split point is defined by successful Regex match.
For instance, say I have an input list:
["file1","A","B","C","file2","D","E","F","G","H","I"]
I want to produce:
[["file1","A","B","C"],["file2","D","E","F","G","H","I"]]
Where the split points, being file1 and file2 were identified by a successful match to
re.search("file[0-9]+",<TEST STRING>)
It is NOT known in advance, the number of items between each split point, nor is it known how many 'fileXXX' terms are in the original vector.
In reality, my Regex matches are a lot more complicated than this, that is not the concern, what I need help with, if someone would be so kind, is the Pythonic way to execute the split logic?
Assumes the first element will be a proper header. If not, you will need to do some defensive clauses.
import re
result = []
pattern = re.compile(r'^file.*')
for el in input_list:
if pattern.match(el):
row = []
result.append(row)
row.append(el)
The following should work quite nicely:
import re
input_list = ["file1","A","B","C","file2","D","E","F","G","H","I"]
output_list = []
for item in input_list:
if re.match("file[0-9]+", item):
output_list.append([item])
else:
output_list[-1].append(item)
print output_list
Gives the following result:
[['file1', 'A', 'B', 'C'], ['file2', 'D', 'E', 'F', 'G', 'H', 'I']]
Note, this assumes the first item is a match.
Update
A second approach could be:
input_list = ["1", "2", "file1","A","B","C","file2","D","E","F","G","H","I"]
output_list = []
for item in input_list:
if re.match("file[0-9]+", item) or len(output_list) == 0:
output_list.append([item])
else:
output_list[-1].append(item)
print output_list
This would also cope with the non initial match case:
[['1', '2'], ['file1', 'A', 'B', 'C'], ['file2', 'D', 'E', 'F', 'G', 'H', 'I']]
You can find the indexes of file\d:
indeces = list(i for i,val in enumerate(my_list) if match('file\d', val))
And then simply group by these indexes:
output = [my_list[indeces[0]:indeces[1]], my_list[indeces[1]:]]
>>> from re import match
>>> my_list = ["file1","A","B","C","file2","D","E","F","G","H","I"]
>>> indeces = list(i for i,val in enumerate(my_list) if match('file\d', val))
>>> [my_list[indeces[0]:indeces[1]], my_list[indeces[1]:]]
[['file1', 'A', 'B', 'C'], ['file2', 'D', 'E', 'F', 'G', 'H', 'I']]

Categories

Resources