2

Let's say I have two lists:

listOne = ['a','b','c']
listTwo = ['b','c','c']

What would be the most pythonic way of deleting a specific element from both lists?

Easily done with a for loop, i.e:

for li in (listOne, listTwo):
    li.remove('c')

Is there a way to do something like this?

[listOne, listTwo].remove('c')
user2442072
  • 437
  • 2
  • 7
  • 16
  • 1
    Keep in mind that `remove` will only remove a single `'c'` from each list in your example. If you want to remove all of them, a list comprehension is likely most idiomatic `listOne = [i for i in listOne if i != 'c']` – Patrick Haugh Jul 11 '18 at 00:06
  • @PatrickHaugh There will never be duplicates in the list, that was just for clarity, but thank you for the reminder. I do need to actually remove the items from the existing lists as well, not just create a new list. – user2442072 Jul 11 '18 at 00:33
  • 1
    Your for loop is perfectly Pythonic. – juanpa.arrivillaga Jul 11 '18 at 01:00
  • To add to @juanpa.arrivillaga's note, regular `for` loops are usually preferred when side effects are involved. Comprehensions and `map` calls are used when you're only transforming data without modifying state. (Note that mixing the two into a single loop is discouraged.) – jpmc26 Jul 11 '18 at 02:35

2 Answers2

1

Based on juanpa's comment, here's a more pythonic approach.

listOne = ['a','b','c']
listTwo = ['c','d','e']

for l in [listOne, listTwo]:
  try:
    l.remove('c')
  except ValueError:
    pass
Daniel Smith
  • 2,334
  • 1
  • 6
  • 9
0

EDIT: Avoid the following code. Generally speaking, avoid doing list comprehension with side effects.

listOne = ['a','b','c']
listTwo = ['c','d','e']
[l.remove('c') for l in [listOne, listTwo] if 'c' in l]  # don't do it
ujhuyz0110
  • 383
  • 1
  • 8
  • I'd say that's perfectly pythonic. Keep in mind that `list.remove(x)` will raise an error if the item isn't present in a list, so I'd recommend `[l.remove('c') for l in [listOne, listTwo] if 'c' in l]` instead. – Daniel Smith Jul 11 '18 at 00:52
  • nice catch! @DanielSmith – ujhuyz0110 Jul 11 '18 at 00:58
  • 3
    This is **absolutely not Pythonic** . Never use list comprehensions for side effects – juanpa.arrivillaga Jul 11 '18 at 00:59
  • In this case, what would you suggest then, juanpa? A simple for loop? – ujhuyz0110 Jul 11 '18 at 01:02
  • [Did a quick search](https://stackoverflow.com/questions/5753597/is-it-pythonic-to-use-list-comprehensions-for-just-side-effects), and I stand corrected, @juanpa.arrivillaga ... Looks like the preferred approach would be a simple `for ... in` loop? – Daniel Smith Jul 11 '18 at 01:06
  • 2
    Yes. A for loop is about as Pythonic as it gets. – juanpa.arrivillaga Jul 11 '18 at 01:14
  • @DanielSmith Thanks for the research! I learned something today! – ujhuyz0110 Jul 11 '18 at 01:16
  • I'm ashamed to admit I did too! After doing some digging it makes perfect sense why people highly recommend against using list comprehension for side effects, as the intermediate list it creates can be expensive and potentially very large. You won't have any ridiculous storage cost incurred with the `for ... in` approach, however. – Daniel Smith Jul 11 '18 at 01:19
  • @DanielSmith more fundamentally though, it mixes a nice functional construct with state change. It's just icky. – juanpa.arrivillaga Jul 11 '18 at 01:31
  • Yeah, that does sound icky. – Daniel Smith Jul 11 '18 at 01:39