简体   繁体   中英

How to get ('a', 'a/b', 'a/b/c') from ('a', 'b', 'c')?

How can I go from this structure

>>> input = ['a', 'b', 'c']

to this one

>>> output 
['a', 'a/b', 'a/b/c']

in an elegant (functional) way?

For now I have this:

>>> from functools import reduce
>>> res = []
>>> for i in range(len(input)):
...     res.append(reduce(lambda a, b: a + '/' + b, input[:i+1]))
... 
>>> res
['a', 'a/b', 'a/b/c']

You can use itertools.accumulate() :

from itertools import accumulate
l = ['a', 'b', 'c']
print(list(accumulate(l, '{}/{}'.format)))

This outputs:

['a', 'a/b', 'a/b/c']

This should work:

l = ['a', 'b', 'c']
new_list =[]
for i in range(len(l)):
    new_list.append("/".join([a for a in l[:i+1]]))

You can do this using a simple list comprehension.

l = ['a', 'b', 'c']
['/'.join(l[:i]) for i in range(1, len(l)+1)]
# ['a', 'a/b', 'a/b/c']

If performance is important, you can roll out your own implementation of accumulate :

out = [l[0]]
for l_ in l[1:]:
    out.append('{}/{}'.format(out[-1], l_))

out
# ['a', 'a/b', 'a/b/c']

This turns out to be slightly faster than itertools for the given problem.

If you must use reduce you could do it like this:

from functools import reduce

input = ['a', 'b', 'c']
output =  [reduce(lambda a, b: f"{a}/{b}", input[:n + 1]) for n in range(0, len(input))]

I prefer the built in join function:

output =  ['/'.join(input[:n + 1]) for n in range(0, len(input))]

You can use count to slice a string in steps:

from itertools import count

input = ['a', 'b', 'c']

s = '/'.join(input)
c = count(1, 2)
[s[:next(c)] for _ in input]
# ['a', 'a/b', 'a/b/c']

a recursive solution:

The idea is quite simple, we use divide and conquer. Problem can be solved if we know the answer to the first n-1 string(or char), in this case, what we need to do is just collect all the characters in one string and separate them by '/'('a/b/c' in this case).

we pass an empty list as the 2nd parameter to store the result.

input = ['a', 'b', 'c']

def foo(list1, list2):
    if (len(list1) == 0):
        return list2
    else:
        s = list1[0]
        for char in list1[1:]:
            s += '/' + char
        list2.insert(0, str)
        return foo(list1[:-1], list2)

>>> foo(input, [])

['a', 'a/b', 'a/b/c']

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