Split and Append a list - python

I have a list as follows:
['aaa > bbb', 'ccc > ddd', 'eee > ']
I am looking to split the list to get the following result, with an empty string element at the end
['aaa', 'bbb', 'ccc', 'ddd', 'eee','']
I tried the following code
for element in list:
list.append(element.split(' > '))
I am getting answer as follows:
[['aaa', 'bbb'], ['ccc', 'ddd'], ['eee','']]
After thinking I see that is what it supposed to work as. So how can I achieve what I am looking for.

You can use list comprehension:
l = ['aaa > bbb', 'ccc > ddd', 'eee > ']
[item.strip() for sublist in [element.split(">") for element in l] for item in sublist]
The output is:
['aaa', 'bbb', 'ccc', 'ddd', 'eee', '']
I admit that this list comprehension is not super easy and understandable but it's a one-liner :)

Try this:
for element in list:
list.extend(element.split(' > '))
From the docs:
list.extend(iterable)
Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.

You can try the following:
a = ['aaa > bbb', 'ccc > ddd', 'eee > ']
newlist = []
for element in a:
newlist += element.split(' > ')
Append method just adds the argument as a new element, the simple addition solves your problem.

Related

Split The Second String of Every Element in a List into Multiple Strings

I am very very new to python so I'm still figuring out the basics.
I have a nested list with each element containing two strings like so:
mylist = [['Wowza', 'Here is a string'],['omg', 'yet another string']]
I would like to iterate through each element in mylist, and split the second string into multiple strings so it looks like:
mylist = [['wowza', 'Here', 'is', 'a', 'string'],['omg', 'yet', 'another', 'string']]
I have tried so many things, such as unzipping and
for elem in mylist:
mylist.append(elem)
NewList = [item[1].split(' ') for item in mylist]
print(NewList)
and even
for elem in mylist:
NewList = ' '.join(elem)
def Convert(string):
li = list(string.split(' '))
return li
print(Convert(NewList))
Which just gives me a variable that contains a bunch of lists
I know I'm way over complicating this, so any advice would be greatly appreciated
You can use list comprehension
mylist = [['Wowza', 'Here is a string'],['omg', 'yet another string']]
req_list = [[i[0]]+ i[1].split() for i in mylist]
# [['Wowza', 'Here', 'is', 'a', 'string'], ['omg', 'yet', 'another', 'string']]
I agree with #DeepakTripathi's list comprehension suggestion (+1) but I would structure it more descriptively:
>>> mylist = [['Wowza', 'Here is a string'], ['omg', 'yet another string']]
>>> newList = [[tag, *words.split()] for (tag, words) in mylist]
>>> print(newList)
[['Wowza', 'Here', 'is', 'a', 'string'], ['omg', 'yet', 'another', 'string']]
>>>
You can use the + operator on lists to combine them:
a = ['hi', 'multiple words here']
b = []
for i in a:
b += i.split()

Python: for-in loop is not checking the last string in a list, why?

I'm using a for-in loop to remove any strings from a list titled "words" that start with "x" as part of a function, but find that this loop will not check the last string in the list. Why is this?
After adding some print statements to figure out where things were going wrong I narrowed it down to the second for-in loop, but beyond that I'm not sure what to do...
def front_x(words):
print '\n'
words.sort()
print words
words2 = []
for string in words:
if string[0] == 'x':
words2.append(string)
#print 'added ' + string + ' to words2'
#else:
#print '(append)checked ' + string
for string in words:
if string[0] == 'x':
words.remove(string)
print 'removed ' + string
else: print 'checked ' + string
words2.extend(words)
return words2
As you can see, in each case it will check all of the elements in the list printed above except for the last. Below that are what my program got vs what it is supposed to get.
['axx', 'bbb', 'ccc', 'xaa', 'xzz']
checked axx
checked bbb
checked ccc
removed xaa
X got: ['xaa', 'xzz', 'axx', 'bbb', 'ccc', 'xzz']
expected: ['xaa', 'xzz', 'axx', 'bbb', 'ccc']
['aaa', 'bbb', 'ccc', 'xaa', 'xcc']
checked aaa
checked bbb
checked ccc
removed xaa
X got: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc', 'xcc']
expected: ['xaa', 'xcc', 'aaa', 'bbb', 'ccc']
['aardvark', 'apple', 'mix', 'xanadu', 'xyz']
checked aardvark
checked apple
checked mix
removed xanadu
X got: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix', 'xyz']
expected: ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
You are mutating the list as you are iterating over it. Behind the scenes Python is stepping through the numeric index of each item in the list. When you remove an item, all of the items with a higher index are shifted.
Instead, build an list of the indices you want to remove, then remove them. Or use a list comprehension to build a new list.
def front_x(words):
words2 = [w for w in words if w.startswith('x')]
return words2
If you want to also mutate the original list (modify words) with the function you can do so using:
def drop_front_x(words):
words2 = []
indices = [i for i, w in enumerate(words) if w.startswith('x')]
for ix in reversed(indices):
words2.insert(0, words.pop(ix))
return words2
I think you need this to get a list as you expected result looks like:
not_xes = [i for i in words if not i.startswith('x')]
xes = [i for i in words if i.startswitch('x')]
expected_result = xes + not_xes

Replace duplicates in a list column

I got a list, in one (the last) column is a string of comma separated items:
temp = ['AAA', 'BBB', 'CCC-DDD', 'EE,FFF,FFF,EE']
Now I want to remove the duplicates in that column.
I tried to make a list out of every column:
e = [s.split(',') for s in temp]
print e
Which gave me:
[['AAA'], ['BBB'], ['CCC-DDD'], ['EE', 'FFF', 'FFF', 'EE']]
Now I tried to remove the duplicates with:
y = list(set(e))
print y
What ended up in an error
TypeError: unhashable type: 'list'
I'd appreciate any help.
Edit:
I didn't exactly said what the end result should be. The list should look like that
temp = ['AAA', 'BBB', 'CCC-DDD', 'EE', 'FFF']
Just the duplicates should get removed in the last column.
Apply set on the elements of the list not on the list of lists. You want your set to contain the strings of each list, not the lists.
e = [list(set(x)) for x in e]
You can do it directly as well:
e = [list(set(s.split(','))) for s in temp]
>>> e
[['AAA'], ['BBB'], ['CCC-DDD'], ['EE', 'FFF']]
you may want sorted(set(s.split(','))) instead to ensure lexicographic order (sets aren't ordered, even in python 3.7)
for a flat, ordered list, create a flat set comprehension and sort it:
e = sorted({x for s in temp for x in s.split(',')})
result:
['AAA', 'BBB', 'CCC-DDD', 'EE', 'FFF']
Here is solution, that uses itertools.chain method
import itertools
temp = ['AAA', 'BBB', 'CCC-DDD', 'EE,FFF,FFF,EE']
y = list(set(itertools.chain(*[s.split(',') for s in temp])))
# ['EE', 'FFF', 'AAA', 'BBB', 'CCC-DDD']
a = ['AAA', 'BBB', 'CCC-DDD', 'EE,FFF,FFF,EE']
b = [s.split(',') for s in a]
c = []
for i in b:
c = c + i
c = list(set(c))
['EE', 'FFF', 'AAA', 'BBB', 'CCC-DDD']
Here is a pure functional way to do it in Python:
from functools import partial
split = partial(str.split, sep=',')
list(map(list, map(set, (map(split, temp)))))
[['AAA'], ['BBB'], ['CCC-DDD'], ['EE', 'FFF']]
Or as I see the answer doesn't need lists inside of a list:
from itertools import chain
list(chain(*map(set, (map(split, temp)))))
['AAA', 'BBB', 'CCC-DDD', 'EE', 'FFF']

How to convert list of lists in tuple to list of lists in python?

I have this as output:
L = ([['AAA', '193.0', 'GGG']], [['BBB', '196.33333333333334', 'TTT']],
[['CCC', '18.666666666666668', 'AAA']])
I want it to be converted to a list of lists like:
L = [['AAA', '193.0', 'GGG'], ['BBB', '196.33333333333334', 'TTT'],
['CCC', '18.666666666666668', 'AAA']]
I have tried to use
L = list(L)
and
[list(elem) for elem in L]
and
L = map(list, L)
But I cannot get any of them to work.
Can someone please help me out?
You could use any of these:
list(zip(*L)[0])
[item for subitem in L for item in subitem]
list(itertools.chain(*L))
functools.reduce(lambda x, y: x + y, L)
First solution
list(zip(*L)[0])
First solution converts resulting tuple in list, just like you wanted. But if result is just used for reading, you do not need a list. tuple will be just fine.
Second solution
[item for subitem in L for item in subitem]
Second case will flatten even this:
L = ([['AAA', '193.0', 'GGG'], ['AAA', '193.0', 'GGG']], [['BBB', '196.33333333333334', 'TTT']], [['CCC', '18.666666666666668', 'AAA']])
to
[['AAA', '193.0', 'GGG'],
['AAA', '193.0', 'GGG'],
['BBB', '196.33333333333334', 'TTT'],
['CCC', '18.666666666666668', 'AAA']]
Third solution
list(itertools.chain(*L))
Third solution is even prettier. What it does it goes through a list of iterables and returns each iterable's elements.
Fourth solution
functools.reduce(lambda x, y: x + y, L)
This solution is just to show how else you can accomplish this.
you have a list of lists inside your tuple, but each list contains one element.
Rebuild the list using a list comprehension, taking the one and only element of the list:
L = ([['AAA', '193.0', 'GGG']], [['BBB', '196.33333333333334', 'TTT']],
[['CCC', '18.666666666666668', 'AAA']])
L = [x[0] for x in L]
print(L)
result:
[['AAA', '193.0', 'GGG'], ['BBB', '196.33333333333334', 'TTT'], ['CCC', '18.666666666666668', 'AAA']]
Your logic is flawed. You have a tuple of single-element lists containing lists, and you just want a list of lists. So you need to extract the first element of each list:
L = [elem[0] for elem in L]
Numpy's squeeze removes extra dimensions from lists and tuples.
from numpy import squeeze
L = squeeze(L).tolist()
This could be done using map, typical use map(function, iterable)
In python 2.7 map returns a list of the result of applying the function to each item in the iterable. so we can use
L = map(lambda l:l[0],L)
In python 3.x map returns an iterator that applies function to every item of iterable(this is the tuple in our case), yielding the results, so list will be required to convert the resulting iterator to a list. i.e.
L = list(map(lambda l:l[0],L))
In either cases, the output of print(L) will be
[['AAA', '193.0', 'GGG'],
['BBB', '196.33333333333334', 'TTT'],
['CCC', '18.666666666666668', 'AAA']]
The function lambda l: l[0] is an anonymous function that takes a list and return the first element in it. in other words it squeezes the list elements of the tuple.

python list different way than googles solution

I am working on the exercises for python from Google and I can't figure out why I am not getting the correct answer for a list problem. I saw the solution and they did it differently then me but I think the way I did it should work also.
# B. front_x
# Given a list of strings, return a list with the strings
# in sorted order, except group all the strings that begin with 'x' first.
# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields
# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
# Hint: this can be done by making 2 lists and sorting each of them
# before combining them.
def front_x(words):
# +++your code here+++
list = []
xlist = []
for word in words:
list.append(word)
list.sort()
for s in list:
if s.startswith('x'):
xlist.append(s)
list.remove(s)
return xlist+list
The call is:
front_x(['bbb', 'ccc', 'axx', 'xzz', 'xaa'])
I get:
['xaa', 'axx', 'bbb', 'ccc', 'xzz']
when the answer should be:
['xaa', 'xzz', 'axx', 'b
bb', 'ccc']
I've don't understand why my solution does not work
Thank you.
You shouldn't modify a list while iterating over it. See the for statement documentation.
for s in list:
if s.startswith('x'):
xlist.append(s)
list.remove(s) # this line causes the bug
Try this:
def front_x(words):
lst = []
xlst = []
for word in words:
if word.startswith('x'):
xlst.append(word)
else:
lst.append(word)
return sorted(xlst)+sorted(lst)
>>> front_x(['bbb', 'ccc', 'axx', 'xzz', 'xaa'])
['xaa', 'xzz', 'axx', 'bbb', 'ccc']

Categories