0

Let's say that we have a simple code:

chars = ["a", "a", "b"]

added = []
for c in chars:
  if c in added:
    added.append(c + '_added_again')
  else:
    added.append(c)

# added is ['a', 'a_added_again', 'b']

We are calling added that is being extend inside loop.

The question is, is it possible to reproduce this behavior with list comprehension?

Something like

chars = ["a", "a", "b"]
added = [
  c + '_added_again' if c in {something like `self` or `this` here, or maybe lambda can be used?} else c for c in chars
]

And same question about map. Is it possible to access list that is still under construction inside map function?

added = list(map(lambda x: x + '_added_again' if ??? else x, chars))

Why I asked this? Just for curiosity.

rzlvmp
  • 7,512
  • 5
  • 16
  • 45

2 Answers2

1

For list comprehension, see my old answer. We can use the same technique in that map anti-pattern as well. Remember all list ids when the lambda is created and find the new list when the lambda is first called.

import gc

chars = ["a", "a", "b"]

def lists():
    return (
       obj
       for obj in gc.get_objects()
       if type(obj) is list
    )

added = list(map(
    lambda x, selfholder=[], list_ids=set(map(id, lists())):
        x + '_added_again'
        if x in (
            selfholder
            or selfholder.extend(L for L in lists() if id(L) not in list_ids)
            or selfholder
        )[0]
        else x,
    chars
))

print(added)

Attempt This Online!

Kelly Bundy
  • 23,480
  • 7
  • 29
  • 65
  • Nice! I like these python tricks. `lambda ... selfholder=[]` was a huge hint. Using this we able to create permanent `selfholder` list on the fly. I used this hint to create my own answer. I think it is more elegant and simpler. However, both of answers are not production ready and more complicated than standard `for` loop... I expected to see shorter solution. – rzlvmp Apr 20 '23 at 09:14
-1

I found a possible one-liner solution for map function:

print(
  list(
    map(lambda x, l=[]: x + '_added_again' if (x in l) or l.append(x) else x, ["a", "a", "b"])
  )
)

Because lists in python is accessed by reference l argument will be same list object until lambda exists. So we able to append elements to this continuously existent list and check if values already added.

However, this answer is not answering the main question. Because we are creating another list to be able check if element is already added or not. The question is: is it possible to access entire comprehension list.

rzlvmp
  • 7,512
  • 5
  • 16
  • 45