1

Suppose such a dict with multiple items:

d = {'foo':['c', 'a', 't'], 'bar':['d', 'o', 'g']}

I'd like to produce

    l = ['c', 'a', 't', 'd', 'o', 'g']
    In [75]: l = []
        ...: for i in d.values():
        ...:     l.extend(i)
        ...: print(l)
    ['c', 'a', 't', 'd', 'o', 'g']

Try to implement it within one line using extend method.

    In [76]: [ [].extend(i) for i in d.values() ]
    Out[76]: [None, None]
    In [79]: [ list().extend(i) for i in d.values()]
    Out[79]: [None, None]

What's the principles behind list comprehension to output [None, None] ?

It's facile to be achieved by

    In [78]: [i for j in d.values() for i in j]
    Out[78]: ['c', 'a', 't', 'd', 'o', 'g']

Is it possible to be done with extend methond in single line?

AbstProcDo
  • 17,381
  • 14
  • 68
  • 114
  • 2
    Possible duplicate of [Unexpected Behavior of Extend with a list in Python](https://stackoverflow.com/questions/7507289/unexpected-behavior-of-extend-with-a-list-in-python) – ducminh Apr 06 '18 at 07:26
  • 3
    `extend` method updates the existing list(the list which calls the extend ) and returns `None`. – Sohaib Farooqi Apr 06 '18 at 07:27
  • 1
    `extend` modifies the list in-place and the return value of `extend` is None – Vikas Periyadath Apr 06 '18 at 07:28
  • TypeError: list() takes at most 1 argument (2 given) @Norrius – AbstProcDo Apr 06 '18 at 07:42
  • @Tool If you want a one-liner, this should do: `import itertools; list(itertools.chain(*d.values()))`. [Docs.](https://docs.python.org/3/library/itertools.html?highlight=itertools#itertools.chain) Note that the order of elements in `.values()` might be not well-defined. – Norrius Apr 06 '18 at 09:12

2 Answers2

1

straight answer: The result you desire can not be constructed in one line with extend

As many already mentioned in comment extend modifies list and returns None.

You are not getting result because you wrote: [].extend(i) in list comprehension

for each iteration your code will construct new list element [] and extend it with iteration value i you passed but it isn't stored anywhere so your code will perform operation but you won't get desire result because you didn't constructed a list before to avoid it you need to write code like this:

l=[]  # create a list first
[l.extend(i) for i in d.values()]  # for each iteration list l will be extended
print(l)  # ['c', 'a', 't', 'd', 'o', 'g']
Gahan
  • 3,870
  • 4
  • 22
  • 41
0

This comply with the principle of Command–query separation - Wikipedia devised by Bertrand Meyer.
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.

Design by contract - Wikipedia

Fluent interface - Wikipedia

AbstProcDo
  • 17,381
  • 14
  • 68
  • 114