Python 2: AttributeError: 'list' object has no attribute 'strip' - python

I have a small problem with list. So i have a list called l:
l = ['Facebook;Google+;MySpace', 'Apple;Android']
And as you can see I have only 2 strings in my list. I want to separate my list l by ';' and put my new 5 strings into a new list called l1.
How can I do that?
And also I have tried to do this like this:
l1 = l.strip().split(';')
But Python give me an error:
AttributeError: 'list' object has no attribute 'strip'
So if 'list' object has no attribute 'strip' or 'split', how can I split a list?
Thanks

strip() is a method for strings, you are calling it on a list, hence the error.
>>> 'strip' in dir(str)
True
>>> 'strip' in dir(list)
False
To do what you want, just do
>>> l = ['Facebook;Google+;MySpace', 'Apple;Android']
>>> l1 = [elem.strip().split(';') for elem in l]
>>> print l1
[['Facebook', 'Google+', 'MySpace'], ['Apple', 'Android']]
Since, you want the elements to be in a single list (and not a list of lists), you have two options.
Create an empty list and append elements to it.
Flatten the list.
To do the first, follow the code:
>>> l1 = []
>>> for elem in l:
l1.extend(elem.strip().split(';'))
>>> l1
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']
To do the second, use itertools.chain
>>> l1 = [elem.strip().split(';') for elem in l]
>>> print l1
[['Facebook', 'Google+', 'MySpace'], ['Apple', 'Android']]
>>> from itertools import chain
>>> list(chain(*l1))
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']

What you want to do is -
strtemp = ";".join(l)
The first line adds a ; to the end of MySpace so that while splitting, it does not give out MySpaceApple
This will join l into one string and then you can just-
l1 = strtemp.split(";")
This works because strtemp is a string which has .split()

This should be what you want:
[x for y in l for x in y.split(";")]
output:
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']

Hope this helps :)
>>> x = [i.split(";") for i in l]
>>> x
[['Facebook', 'Google+', 'MySpace'], ['Apple', 'Android']]
>>> z = [j for i in x for j in i]
>>> z
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']
>>>

One possible solution I have tried right now is:
(Make sure do it in general way using for, while with index)
>>> l=['Facebook;Google+;MySpace', 'Apple;Android']
>>> new1 = l[0].split(';')
>>> new1
['Facebook', 'Google+', 'MySpace']
>>> new2= l[1].split(';')`enter code here`
>>> new2
['Apple', 'Android']
>>> totalnew = new1 + new2
>>> totalnew
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']

You can first concatenate the strings in the list with the separator ';' using the function join and then use the split function in order create the list:
l = ['Facebook;Google+;MySpace', 'Apple;Android']
l1 = ";".join(l).split(";")
print l1 #printing
outputs
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']

You split the string entry of the list. l[0].strip()

Split the strings and then use chain.from_iterable to combine them into a single list
>>> import itertools
>>> l = ['Facebook;Google+;MySpace', 'Apple;Android']
>>> l1 = [ x for x in itertools.chain.from_iterable( x.split(';') for x in l ) ]
>>> l1
['Facebook', 'Google+', 'MySpace', 'Apple', 'Android']

Related

Converting nested tuple into nested list in python

I have nested tuple like below wanted to convert into nested list in the format mentioned
Input:
T = [('id','1'),('name','Mike'),('Adrs','Tor')]
Output:
L = [['id','1'],['name','Mike'],['Adrs','Tor']]
>>> spam = [('id','1'),('name','Mike'),('Adrs','Tor')]
>>> eggs = [list(item) for item in spam]
>>> eggs
[['id', '1'], ['name', 'Mike'], ['Adrs', 'Tor']]
You could unpack each separate tuple and then append it
L = []
for item in T:
a, b = item
L.append([a,b])
l = [('id','1'),('name','Mike')]
m = [[], []]
for i in range(len(l)):
m[i] = [l[i][0], l[i][1]]
print(m)

Loop through a list of strings and remove all items after a specific list item(i) where i can be a or b or c

Search through the list and remove everything else inclusive and after either Audi or Mazda or Suzuki. Please note Only one of the 3 can be in the list but not two or all of them. Just one of them
First Scenario: if it's Audi,
Give a list (list items are random):
lst = ["Nissan","Chevrolet","Audi","Mercedes","BMW","Subaru","Mitsubishi"]
Expected result:
new_lst = ["Nissan","Chevrolet"]
Scenario 2 : If it's Suzuki.
Expected result
lst = ["Nissan","Chevrolet","Mercedes","BMW","Subaru","Suzuki","Mitsubishi"]
new_lst = ["Nissan","Chevrolet","Mercedes","BMW","Subaru"]
etc etc
You can use itertools.takewhile to crate a new list and 'break' out at the appropriate point
>>> from itertools import takewhile
>>> lst = ["Nissan","Chevrolet","Audi","Mercedes","BMW","Subaru","Mitsubishi"]
>>> list(takewhile(lambda x: x != "Audi", lst))
['Nissan', 'Chevrolet']
Use list slicing with list.index
Ex:
lst = ["Nissan","Chevrolet","Audi","Mercedes","BMW","Subaru","Mitsubishi"]
print(lst[:lst.index("Audi")])
lst = ["Nissan","Chevrolet","Mercedes","BMW","Subaru","Suzuki","Mitsubishi"]
print(lst[:lst.index("Suzuki")])
Output:
['Nissan', 'Chevrolet']
['Nissan', 'Chevrolet', 'Mercedes', 'BMW', 'Subaru']

Python: How to sort a list based on another list

I want to order list1 based on the strings in list2. Any elements in list1 that don't correspond to list2 should be placed at the end of the correctly ordered list1.
For example:
list1 = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
list2 = ['Bananas', 'Oranges', 'Pear']
list1_reordered_correctly= ['Title1-Bananas','Title1-Oranges','Title1-Pear','Title1-Apples']
Here's an idea:
>>> def keyfun(word, wordorder):
... try:
... return wordorder.index(word)
... except ValueError:
... return len(wordorder)
...
>>> sorted(list1, key=lambda x: keyfun(x.split('-')[1], list2))
['Title1-Bananas', 'Title1-Oranges', 'Title1-Pear', 'Title1-Apples']
To make it neater and more efficient (index has to traverse the list to find the right item), consider defining your word-order as a dictionary, i.e.:
>>> wordorder = dict(zip(list2, range(len(list2))))
>>> wordorder
{'Pear': 2, 'Bananas': 0, 'Oranges': 1}
>>> sorted(list1, key=lambda x: wordorder.get(x.split('-')[1], len(wordorder)))
['Title1-Bananas', 'Title1-Oranges', 'Title1-Pear', 'Title1-Apples']
This answer is conceptual rather than efficient.
st1dict = dict((t.split('-')[1],t) for t in st1) #keys->titles
list2titles = list(st1dict[k] for k in list2) #ordered titles
extras = list(t for t in st1 if t not in list2titles) #extra titles
print(list2titles+extras) #the desired answer
One liner.
sorted_list = sorted(list1, key=lambda x: list2.index(x.split('-')[1]) if x.split('-')[1] in list2 else len(list2) + 1)
Use code below to achieve desired sorting:
list1 = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
list2 = ['Bananas', 'Pear']
# note: converting to set would improve performance of further look up
list2 = set(list2)
def convert_key(item):
return int(not item.split('-')[1] in list2)
print sorted(list1, key=convert_key)
# ['Title1-Pear', 'Title1-Bananas', 'Title1-Apples', 'Title1-Oranges']
something like this would get you going on this.
l = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
l2 = ['Bananas', 'Oranges', 'Pear']
l3 = []
for elem_sub in l2:
for elem_super in l:
if elem_sub in elem_super:
l3.append(elem_super)
print(l3 + list(set(l)-set(l3)))

Updating list in-place

I have a list of strings, some of them ends with new line symbol. I want to modify this list by removing \n from strings which ends with it. For this purpose I use the following code:
aList = ['qwerttyy\n', '123454\n', 'zxcv']
for s in aList:
if s.endswith('\n'):
s = s[: -1]
print(s)
The output is the following:
qwerttyy
123454
>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
So the original list wasn't changed though list is mutable object. What is the reason of such behavior?
You can use slice assignment and a list comprehension:
>>> foo = aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s[:-1] if s.endswith('\n') else s for s in aList]
>>> foo #All references are affected.
['qwerttyy', '123454', 'zxcv']
>>> aList
['qwerttyy', '123454', 'zxcv']
Your code didn't work because it is equivalent to:
s = aList[0]
if s.endswith('\n'):
s = s[: -1]
s = aList[1]
if s.endswith('\n'):
s = s[: -1]
...
i.e You're updating the variable s, not the actual list item
because the for loop makes copies of strings.
You can use:
[s[:-1] if s.endswith('\n') else s for s in aList]
Maybe this is simpler, though it will remove also whitespaces.
[s.strip() for s in aList]
Using list comprehension and str.rstrip
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> [s.rstrip('\n') for s in aList]
['qwerttyy', '123454', 'zxcv']
Above will create new list. To modify the original list, use slicing (list[:] = ...):
>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s.rstrip('\n') for s in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']
NOTE str.rstrip returns different result from [:-1] when tehre are multiple trailing newlines:
>>> 'qwerttyy\n\n'.rstrip('\n')
'qwerttyy'
>>> 'qwerttyy\n\n'[:-1]
'qwerttyy\n'
try this
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList = [x[:-1] if x.endswith('\n') else x for x in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']

How do you turn a list of strings into a list of sublists with each string in each sublist?

How do you turn a list of strings into a list of sublist of strings?
For example:
List_of_Strings = ['abc','def','ghi']
Desired Output:
[['abc'],['def'],['ghi']]
My hack to get it is:
List_of_Sublist_of_Strings = [(str(x)+",").split(",") for x in List_of_Strings]
Produces:
[['abc', ''], ['def', ''], ['ghi', '']]
This produces an unwanted empty item in the sublists, but perhaps it's not possible to create a list of sublists in which the sublists only have one item.
You need to put those strings in [] there, and it's done.
>>> lis = ['abc','def','ghi']
>>> [[x] for x in lis]
[['abc'], ['def'], ['ghi']]
Use a list comprehension like so:
>>> lst = ['abc','def','ghi']
>>> [[x] for x in lst]
[['abc'], ['def'], ['ghi']]
>>>
Putting x in [] places it in a list of its own.

Categories

Resources