I wanted to ask if there any solution for ommiting this for loop with one liner or anything?
Data = [{"name": "Gill","age": "20", "id":"10001", "gender": "female"}, {"name": "Rakshit", "age": "22", "id":"10002"}]
new_Data = {"id":"10001"}
for i, x in enumerate(Data):
if x['id'] == new_Data['id']:
del Data[i]
CodePudding user response:
You can use list comprehension to achieve this task of filtering:
Data = [{"name": "Gill","age": "20", "id":"10001", "gender": "female"}, {"name": "Rakshit", "age": "22", "id":"10002"}]
new_Data = {"id":"10001"}
filtered_data = [data for data in Data if not data['id'] == new_data['id']]
CodePudding user response:
If you're trying to remove items in-place you can do it with a comprehension, but it's a bit wonky:
>>> lx = [1, 2, 2, 2, 3]
>>> [lx.pop(i) for i in sorted((idx for idx, val in enumerate(lx) if val == 2), reverse=True)]
[2, 2, 2]
>>> lx
[1, 3]
The main thing to note here is you're getting the indexes that you want to delete, and then reversing the order you pop them off in. That way you don't disrupt your later indexes by popping off earlier ones.
If you're concerned about creating an unnecessary list, this is also possible with a generator:
>>> lx = [1, 2, 2, 2, 3]
>>> all(lx.pop(i) for i in sorted((idx for idx, val in enumerate(lx) if val == 2), reverse=True))
True
>>> lx
[1, 3]
Notably, though, there is little reason to go about it this way. The main reason for deleting a list in-place is conservation of memory. But in your case you've got dictionary as list items. Your original list is really just holding pointers to those values, and if you use a simple list comprehension to filter your original list, it too will have references to your dictionary items:
>>> ls = [{"a": 1}, {"b": 2}]
>>> lx = [i for i in ls if i.get("a", False)]
>>> lx
[{'a': 1}]
>>> ls[0]["a"] = 2
>>> ls
[{'a': 2}, {'b': 2}]
>>> lx
[{'a': 2}]
This demonstrates that a change in the original list is mirrored in your filtered list, even after the filter takes place. Thus, the memory you use in creating a new, filtered list is really just the size of the references - relatively small. It is no slower, really, since the memory allocation is O(n), equal to your iteration over the original list. So, while you can modify the original list in-place, there isn't a lot of reason to do so and some pitfalls you avoid (such as the one in your original post, where you could end up skipping items because you're deleting indexes front to back).