List comprehension with split

Viewed 1279

Input: ["0:start:0","1:start:2","1:end:5","0:end:6"]

Output: [[0, "start", 0], [1, "start", 2], ... ]

This one [item.split(":") for item in logs] doesn't convert to int. Tried various ways, but cannot make it to work: [(int(a), b, int(c)) for item in logs for (a,b,c) in item.split(":")]

Thanks!

5 Answers

You can use a generator expression in the list comprehension:

a = ["0:start:0","1:start:2","1:end:5","0:end:6"]
b = [[int(x[0]), x[1], int(x[2])] for x in (item.split(":") for item in a)]
print(b)

Output:

[[0, 'start', 0], [1, 'start', 2], [1, 'end', 5], [0, 'end', 6]]

My answer was inspired by: List comprehensions splitting loop variable

For clarity, I'd do it this way, in two steps:

logs = ["0:start:0", "1:start:2", "1:end:5", "0:end:6"]
split_logs = (log.split(':') for log in logs)
result = [(int(a), b, int(c)) for a, b, c in split_logs]

You can add the map function:

[(int(i), j, int(k)) for i, j, k  in map(lambda x: x.split(':'), lst)]

Try this one:

 [[int(a), b, int(c)] for a,b,c in [item.split(":") for item in logs]]

You came pretty close!

There comes a point where a list comprehension is complex enough that perhaps you really should just use a for loop. However, I think this ends up being pretty readable:

input_list = ['0:start:0', '1:start:2', '1:end:5', '0:end:6']

transformed = [
    [
        int(subitem) if subitem.isdigit() else item
        for part in item.split(':')
    ]
    for item in input_list
]

print(transformed)
>>> [[0, 'start', 0], [1, 'start', 2], [1, 'end', 5], [0, 'end', 6]]

It's one list comprehension nested inside another. The inner one iterates through the subitems of each item in the original list, and converts each one to an int if it contains only digits.

Related