简体   繁体   中英

Elegant way to split a list of strings into nested lists with values of type float

Looking for an elegant way to split/format the below list of strings:

ls = ["12,45 58,96",
      "23,67 94,92 93,10",
      "45,76 33,11 46,33"] 

Goal is nested lists of [x, y] coordinates of type float:

goal = [[[12.0,45.0], [58.0,96.0]],
       [[23.0,67.0], [94.0,92.0], [93.0,10.0]]
       [[etc ......

I have solved this with the below code, but it's rough (and embarrassing,) and I know there has to be a much more elegant way? maybe using list comprehensions or generators?

s = []

for i in ls:
    i.split(' ')
    s.append(i)

res = [i.split(' ') for i in s] # splits at the space

gen = (map(lambda n: n.split(','), x) for x in res) # split list elements at comma
result = (list(x) for x in gen)

final = []

for i in result: # convert each string to a float
    sublist1 = []
    for x in i:
        sub = []
        for z in x:
            z = float(z)
            sub.append(z)
        sublist1.append(sub)
    final.append(sublist1)

print(list(final))

You can try list comprehension like this -

newlist = [[[float(v) for v in e.split(',')] for e in st.split()] for st in l]

Output:

[[[12.0, 45.0], [58.0, 96.0]], [[23.0, 67.0], [94.0, 92.0], [93.0, 10.0]], [[45.0, 76.0], [33.0, 11.0], [46.0, 33.0]]]

Using map

a = ["12,45 58,96", "23,67 94,92 93,10", "45,76 33,11 46,33"]
list(map(lambda x: list(map(lambda a: list(map(float, a.split(","))), x.split(" "))), a))

Honestly, there are so many ways to write this, and if it will look elegant or not, it will depend on what you understand by elegance .

If elegance is terseness and straightforwardness, you can do list comprehension:

[[[float(v) for v in c.split(',')] for c in l.split()] for l in ls]

If elegance is purity, you can write a fully "point-free" functional expression (even without lambdas), that look completely alien:

from functools import partial
list(map(list, map(partial(map, list), (map(partial(map, partial(map, float)), map(partial(map, partial(str.split, sep=',')), map(str.split, ls)))))))

Now, if elegance is clarity and maintainability, you do the most obvious and self documented code:

def as_coords(ls):
  for string in ls:
    arr = []
    for coord in string.split():
      x, y = coord.split(',')
      arr.append([float(x), float(y)])
    yield arr

list(as_coords(ls))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM