2

I have one string list that contains numbers seperated by a comma. I want to create two lists of integers from it. That is:

l=["23,2","11,2","12,7"]

What I want to do is:

l1=[23,11,12]
l2=[2,2,7]

I will appreciate any help.

selubamih
  • 83
  • 3
  • 15

3 Answers3

2

You can use zip:

l=["23,2","11,2","12,7"]
l1, l2 = [list(d) for d in zip(*[[int(i) for i in c.split(',')] for c in l])]

Output:

[23, 11, 12]
[2, 2, 7]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • You can get rid of the outer brackets and make it a generator expression: `l1, l2 = (list(d) for d in zip(*[[int(i) for i in c.split(',')] for c in l]))` – Steven Rumbalski Jul 03 '18 at 17:29
  • @StevenRumbalski Genexp wouldn't make much sense in this case. The data will still be copied multiple times in memory. In this case it will actually take more memory and probably more time. – Bharel Jul 03 '18 at 18:58
  • @Bharel: I'm talking about the outer list comprehension. It's a temporary list that gets thrown away. A generator expression gets evaluated for the argument but not placed into a list. It's the same number of iterations just without the throwaway list. It's the difference between `a, b = [n for n in (1, 2)]` and `a, b = (n for n in (1, 2))`. – Steven Rumbalski Jul 03 '18 at 19:05
  • @StevenRumbalski Now I see what you're saying. I still have a hunch though it'll be slower and take more memory. Internal genexp memory is much larger than a small 2 item list, and creating a throwaway generator is costlier than a throwaway list. For example, you'll see `"".join([listcomp])` will be faster than `"".join(gencomp)` as you're internally creating a list. I think it internally creates a tuple in here out of the genexp. It's pretty interesting actually. Wanna test it? (I can't code on my chromebook easily) – Bharel Jul 03 '18 at 19:10
1

Can you use zip() to rip it apart based on splitting each sting by the comma , and map each substring to an int`.

l = ["23,2","11,2","12,7"]
l1, l2 = zip(*[map(int, x.split(',')) for x in l])
# l1 = (23, 11, 12)
# l2 = (2, 2, 7)
Sunny Patel
  • 7,830
  • 2
  • 31
  • 46
  • 1
    Not my downvote, but the output you claim -- that l1 and l2 become lists of ints -- is wrong. Your code makes them tuples of strings. – DSM Jul 03 '18 at 16:42
1

Ajax1234's way is very pythonic and undoubtedly the best. But maybe this is a bit simpler to understand if new to the language. It uses splicing:

from itertools import chain

l=["23,2","11,2","12,7"]
l = [x.split(',') for x in l] #Split list elements by comma.
l = list(chain.from_iterable(l)) #Get rid of tuples.
list1 = l[::2] #Take every even indexed element, including 0.
list2 = l[1::2] #Takes every odd indexed element.

Output:

[23, 11, 12]
[2, 2, 7]

Here is a link to someone who explains it better.

J. Dykstra
  • 201
  • 1
  • 10
  • `list(chain.from_iterable())` is an unneeded wrinkle considering you were just using a list comprehension on the previous line and could have handled it with an extra layer of nesting (as in `l = [n for x in l for n in x.split(',')]`). Also, you are leaving your list contents as strings, but show your output as lists of integers (so maybe that modified comprehension becomes `l = [int(n) for x in l for n in x.split(',')]`. – Steven Rumbalski Jul 03 '18 at 17:18
  • Now this `l1, l2 = (x[i::2] for x in [[int(n) for s in l for n in s.split(',')]] for i in (0,1))` is some ugly fun code I would never put in an answer. – Steven Rumbalski Jul 03 '18 at 17:20
  • Haha that's awesome man. Really appreciate those edits! Thanks Steven! – J. Dykstra Jul 03 '18 at 18:55