1

I have a list of objects.

My list format:

my_list = [
    {
        "y": "9",
        "x": "num.nine"
    },
    {
        "y": "8",
        "x": "eight"
    },
    {
        "y": "7",
        "x": "num.seven"
    },
    {
        "y": "6",
        "x": "six"
    },
    {
        "y": "5",
        "x": "num.five"
    }
]

I want to delete the objects where my_list['x'] is not like num.

This is what I did:

for val in my_list:
    if('num' not in val['x']):
        del val['x']
        del val['y']

pprint(my_list)

The result of that code is:

[
 {'x': 'num.nine', 'y': '9'},
 {},
 {'x': 'num.seven', 'y': '7'},
 {},
 {'x': 'num.five', 'y': '5'}
]

How do I delete the whole object?

My expected result is:

[
 {'x': 'num.nine', 'y': '9'},
 {'x': 'num.seven', 'y': '7'},
 {'x': 'num.five', 'y': '5'}
]
2
  • 4
    my_list = [obj for obj in my_list if obj['x'].startswith('num.')] Commented Jul 17, 2020 at 20:20
  • list comprehension only returning entries you want, or for loop making a COPY and using my_list.delete, deleting the entries you dont want Commented Jul 17, 2020 at 21:02

4 Answers 4

2

Why delete? Alternatively

my_list = [val for val in my_list if 'num' in val['x']]

You can use filter function as well. (Note that filter in python2 returns a list, and in python3 it returns a iterator)

PS. I am not sure whether the filter condition you have written is exactly what you need, yet I have used the same condition. Most likely you want to include val when val['x'] is starting with "num."

Sign up to request clarification or add additional context in comments.

1 Comment

Terminology note, filter returns an iterator, not a generator.
1

Add what you need to a new list:

new_list = []
for elem in my_list:
    if('num' in elem['x']):
        new_list.append(elem)

Comments

0

The most efficient thing to is probably to use the Python filter function. Consider this example:

>>> my_list = my_list=[ 
         { 
             "y": "9", 
             "x": "num.nine" 
         }, 
         { 
             "y": "8", 
             "x": "eight" 
         }, 
         { 
             "y": "7", 
             "x": "num.seven" 
         }, 
         { 
             "y": "6", 
             "x": "six" 
         }, 
         { 
             "y": "5", 
             "x": "num.five" 
         } 
    ]                                                                                                                                                                                          
>>> my_list = list(filter(lambda item: 'num' in item['x'], my_list))                                                                                                                           
>>> my_list                                                                                                                                                                                    
[{'y': '9', 'x': 'num.nine'},
 {'y': '7', 'x': 'num.seven'},
 {'y': '5', 'x': 'num.five'}]

Note that you're creating a new list with this approach, rather than modifying the old one in place. That's probably a better approach, because if you simultaneously iterate over an object while also modifying it, you'll get surprising results.

12 Comments

In my experience filter() is measurably slower than a list comprehension.
@MarkMeyer, depends on size of initial list. In one of questions I've seen detailed test, but not sure if I can find link now. Upd. Tested with timeit and my simple test shows that list comprehension is slightly slower (I used list with 200 dictionaries for test).
I would be interested to see that @OlvinRoght — with the kind of data and filter in this question, the comprehension is considerably faster whether the list has 5 items or 100000.
The reason a list comprehension may not be more efficient is that if the list is especially large, and you don't cast the output of filter() to a list, you can iterate sequentially over the return value of filter() and it won't have to hold a new list in memory or build it ahead of time.
@KenKinder, I mean that alternatively you can use (obj for obj in my_list if obj['x'].startswith('num.')) which also won't create list in memory.
|
0

you can do it using list comprehension, this would be the answer:

new_list = [obj for obj in my_list if 'num' in obj['x']]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.