2

I have a nested list as shown below:

L = [['James', 'Bob', '23', '47'], ['Earl', 'Carl', '16', '43'], ['Milly', 'Wendy', '1', '21']]

I want to take the names from each of them and put them into a new list called 'newList' without the numbers.

I tried the following code:

for i in L[0][0]:
    newList.append(i)
print(newList)

However, this just printed the first name and each letter was seperated by a comma. I want the new list to look like this:

newList = ['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
Billy Whales
  • 103
  • 1
  • 9
  • Possible duplicate of [Explain Python's slice notation](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) – user2390182 May 09 '17 at 09:46

7 Answers7

3

Just use a nested list comprehension:

In [61]: [i for sub in L for i in sub[:2]]
Out[61]: ['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
Mazdak
  • 105,000
  • 18
  • 159
  • 188
1

You can use isdigit() to filter out names

res = [j for i in L for j in i if not j.isdigit()]
['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
akash karothiya
  • 5,736
  • 1
  • 19
  • 29
1

Do it in two steps.

First, grab the first two elements of each list:

>>> names_nested = [sub[:2] for sub in L]
>>> names_nested
[['James', 'Bob'], ['Earl', 'Carl'], ['Milly', 'Wendy']]

Then unnest this list:

>>> names = [name for sub in names_nested for name in sub]
>>> names
['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']

... or do it more comfortably with itertools.chain:

>>> from itertools import chain
>>> list(chain(*(sub[:2] for sub in L)))
['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']

... or itertools.chain.from_iterable to get rid of the unpacking star and one set of parentheses.

>>> list(chain.from_iterable(sub[:2] for sub in L))
['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
timgeb
  • 76,762
  • 20
  • 123
  • 145
1

You need to iterate over elements in list L

for i in L:
    newList.append(i[0])
    newList.append(i[1])
    #or simply newList.extend(i[:2])
print(newList)

EDIT

for i in L:
    if i[0] not in newList:
        newList.append(i[0])
    if i[1] not in newList:
        newList.append(i[1])
    #or simply newList.extend(i[:2])
print(newList)
itzMEonTV
  • 19,851
  • 4
  • 39
  • 49
  • Thank you! How would I alter this so that if I had a nested list with repeated names it would only print the name once in the new list? – Billy Whales May 09 '17 at 10:02
  • Here `i[0]` is the first element, `i[1]` is the second element.You can check whether equal or not before `append` – itzMEonTV May 09 '17 at 10:06
  • I tried putting `if i[0] != i[1]` after the for statement and before the appending statements. This however just produced the same result as before. – Billy Whales May 09 '17 at 10:12
  • I dont undertand repeating names, is that in same list or in diferent list? – itzMEonTV May 09 '17 at 10:15
  • In a different list, for example: `[['James', 'Alan'], ['Alan', 'James']]` It would only print `['James', 'Alan']` – Billy Whales May 09 '17 at 10:17
0

If the problem is simply the first two elements from each sublist you can do:

from itertools import chain
result = chain.from_iterable(sublist[:2] for sublist in L)

This will produce a chain object, you can use list to evaluate it:

list(result)
# ['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
0

Using numpy to slice the list and flatten the results to a 1D list:

import numpy as np
np.array(L)[:,0:2].flatten().tolist()
Out[349]: ['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
Allen Qin
  • 19,507
  • 8
  • 51
  • 67
0

Use the isdigit method to see if a str is a digit:

[j for l in L for j in l if not j.isdigit()]

Output:

['James', 'Bob', 'Earl', 'Carl', 'Milly', 'Wendy']
elena
  • 3,740
  • 5
  • 27
  • 38