Bharath Kashyap
Bharath Kashyap

Reputation: 343

Python: How to separate list based on numerical values and strings from a given list

Consider I have a list like

listed = [1, 't', 'ret', 89, 95, 'man65', 67, 'rr']

Now I need to write a script which will be like 2 lists; one stringList and numberList where,

stringList = ['t', 'ret', 'man65', 'rr']
numberList = [1, 89, 95, 67]

Upvotes: 0

Views: 2309

Answers (5)

Stefan Pochmann
Stefan Pochmann

Reputation: 28636

numbers, strings = both = [], []
for x in listed:
    both[isinstance(x, str)].append(x)

An alternative as an answer to Ajay's challenge in the comments to do it with just one list comprehension (note: this is a bad solution):

strings = [listed.pop(i) for i, x in list(enumerate(listed))[::-1] if isinstance(x, str)][::-1]
numbers = listed

Another:

numbers, strings = [[x for x in listed if isinstance(x, t)] for t in (int, str)]

Yet another, with the advantage of reading listed only once (inspired by PM 2Ring):

numbers, strings = [[x for x in l if isinstance(x, t)]
                    for l, t in zip(itertools.tee(listed), (int, str))]

Upvotes: 2

ohmu
ohmu

Reputation: 19780

The standard way to check what kind of object you have is by using the isinstance(object, classinfo) function. Using isinstance(...) is preferred over type(object) because type(...) returns the exact type of an object, and does not account for sub-classes when checking types (this is significant in more complex scenarios).

You can check if you have a number (int, float, etc.) by comparing each class individually or with numbers.Number:

# Check for any type of number in Python 2 or 3.
import numbers
isinstance(value, numbers.Number)

# Check for floating-point number in Python 2 or 3.
isinstance(value, float)

# Check for integers in Python 3.
isinstance(value, int)

# Check for integers in Python 2.
isinstance(value, (int, long))

You can check if you have a string (str, bytes, etc.) by comparing with the individual classes which vary depending on whether you're using Python 2 or 3:

# Check for unicode string in Python 3.
isinstance(value, str)

# Check for binary string in Python 3.
isinstance(value, bytes)

# Check for any type of string in Python 3.
isinstance(value, (str, bytes))

# Check for unicode string in Python 2.
isinstance(value, unicode)

# Check for binary string in Python 2.
isinstance(value, str)

# Check for any type of string in Python 2.
isinstance(value, basestring)

So, putting that all together you'd have:

import numbers

stringList = []
numberList = []
for value in mixedList:
    if isinstance(value, str):
        stringList.append(value)
    elif isinstance(value, numbers.Number):
        numberList.append(value)

Upvotes: 6

Łukasz Rogalski
Łukasz Rogalski

Reputation: 23233

Generic solution: grouping by exact object type.

multityped_objects = [1, 't', 'ret', 89, 95, 'man65', 67, 'rr', 12.8]
grouped = {}
for o in multityped_objects:
    try:
        grouped[type(o)].append(o)
    except KeyError:
        grouped[type(o)] = [o]

assert grouped[str] == ['t', 'ret', 'man65', 'rr']
assert grouped[int] == [1, 89, 95, 67]
assert grouped[float] == [12.8]

Upvotes: 1

Ajay
Ajay

Reputation: 5347

In [16]: sl=[i for i in a if isinstance(i,str)]

In [17]: nl=[i for i in a if isinstance(i,int)]

In [18]: sl
Out[18]: ['t', 'ret', 'man65', 'rr']

In [19]: nl
Out[19]: [1, 89, 95, 67]

Upvotes: 1

Tom
Tom

Reputation: 937

You can use the built in type function to test each element in the list, and append it to a list based in its type.

numberList = []
stringList = []

for x in listed:
    if type(x) == int: numberList.append(x)
    else: stringList.append(x)

Upvotes: 1

Related Questions