patternpythonModerate
Weaving elements into a list
Viewed 0 times
intolistweavingelements
Problem
I have the following problem statement:
Modify a given list such that one specific element is "weaved" into that list.
Examples if the element is
I solved it using the following code in Python 3.4:
Is there a better (more Pythonic?) solution to it and is "weaving" the correct operation here?
Modify a given list such that one specific element is "weaved" into that list.
Examples if the element is
'module':[]remains[]
['a']remains['a']
['a', 'b']becomes['a', 'module', 'b']
['a', 'b', 'c']becomes['a', 'module', 'b', 'module', 'c']
I solved it using the following code in Python 3.4:
@staticmethod
def __weave_element_into_list(element, values: list) -> list:
"""
Weaves an element into a given list.
Examples if the element is 'module':
- Input [] remains [].
- Input ['a'] remains ['a'].
- Input ['a', 'b'] becomes ['a', 'module', 'b'].
- Input ['a', 'b', 'c'] becomes ['a', 'module', 'b', 'module', 'c'].
- etc.
:param element: The element to weave into the list
:param values: The original list
:return: The list with element weaved into it.
"""
copy_list = list(values)
if len(copy_list) <= 1:
return copy_list
i = 1
while i < len(copy_list):
copy_list.insert(i, element)
i += 2
return copy_listIs there a better (more Pythonic?) solution to it and is "weaving" the correct operation here?
Solution
The function could be replaced with this line:
Essentially,
zipping
About your original implementation, instead of this:
This is more Pythonic:
I'm also wondering if this needs to be a
Since it's a pure function, I'd just call it weave.
Here's the complete implementation with doctests:
I see @jonrsharpe beat me to the doctests.
To add something new,
another way to run doctests:
Update
Originally I proposed this one-liner:
But that turns out to be a bad idea.
This other discussion is also illuminating.
return list(chain.from_iterable(zip(values, [element] * len(values))))[:-1]Essentially,
zipping
values with another list of the same size containing element in all values, flattening the zip, and chopping off the end.About your original implementation, instead of this:
if len(copy_list) <= 1:
return copy_listThis is more Pythonic:
if not copy_list:
return copy_listI'm also wondering if this needs to be a
@staticmethod.Since it's a pure function, I'd just call it weave.
Here's the complete implementation with doctests:
from itertools import chain
def weave(element, values: list) -> list:
"""
>>> weave('module', [])
[]
>>> weave('module', ['a'])
['a']
>>> weave('module', ['a', 'b'])
['a', 'module', 'b']
>>> weave('module', ['a', 'b', 'c'])
['a', 'module', 'b', 'module', 'c']
:param element: The element to weave into the list
:param values: The original list
:return: The list with element weaved into it.
"""
return list(chain.from_iterable(zip(values, [element] * len(values))))[:-1]I see @jonrsharpe beat me to the doctests.
To add something new,
another way to run doctests:
python -m doctest yourfile.pyUpdate
Originally I proposed this one-liner:
return sum(zip(values, [element] * len(values)), ())[:-1]But that turns out to be a bad idea.
This other discussion is also illuminating.
Code Snippets
return list(chain.from_iterable(zip(values, [element] * len(values))))[:-1]if len(copy_list) <= 1:
return copy_listif not copy_list:
return copy_listfrom itertools import chain
def weave(element, values: list) -> list:
"""
>>> weave('module', [])
[]
>>> weave('module', ['a'])
['a']
>>> weave('module', ['a', 'b'])
['a', 'module', 'b']
>>> weave('module', ['a', 'b', 'c'])
['a', 'module', 'b', 'module', 'c']
:param element: The element to weave into the list
:param values: The original list
:return: The list with element weaved into it.
"""
return list(chain.from_iterable(zip(values, [element] * len(values))))[:-1]python -m doctest yourfile.pyContext
StackExchange Code Review Q#92286, answer score: 11
Revisions (0)
No revisions yet.