Python Forum

Full Version: How to remove dict from a list?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello all

I have created this list with dictionary for all video files with their media details. I want to remove all dictonaries records from the list where 'format' is not 'HEVC'.

#!/usr/bin/env python3                                                           
                                                                                    
old_list = [                                                                        
{'fname': 'Welcome.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 118.867, 'framerate': 30.0, 'fsize_byte': 4095489},
{'fname': 'tut.webm', 'format': 'VP9', 'width': 1152, 'height': 720, 'duration': 535.633, 'framerate': 23.976, 'fsize_byte': 17017448},
{'fname': 'Line.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 141.8, 'framerate': 25.0, 'fsize_byte': 4495620},
{'fname': 'CAPITAL.MP4', 'format': 'AVC', 'width': 1280, 'height': 720, 'duration': 284.3, 'framerate': 30.0, 'fsize_byte': 26107717},
]                                                                                
                                                                                 
new_list = []                                                                    
                                                                                 
for i in old_list:                                                               
    print(i)                                                                     
                                                                                 
for rec in old_list:                                                             
    if rec.get('format') != 'HEVC':                                              
        new_list.append(rec)                                                     
                                                                                 
print()                                                                          
                                                                                 
for j in new_list:                                                               
    print(j) 
The output is like this:

Output:
{'fname': 'Welcome.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 118.867, 'framerate': 30.0, 'fsize_byte': 4095489} {'fname': 'tut.webm', 'format': 'VP9', 'width': 1152, 'height': 720, 'duration': 535.633, 'framerate': 23.976, 'fsize_byte': 17017448} {'fname': 'Line.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 141.8, 'framerate': 25.0, 'fsize_byte': 4495620} {'fname': 'CAPITAL.MP4', 'format': 'AVC', 'width': 1280, 'height': 720, 'duration': 284.3, 'framerate': 30.0, 'fsize_byte': 26107717} {'fname': 'tut.webm', 'format': 'VP9', 'width': 1152, 'height': 720, 'duration': 535.633, 'framerate': 23.976, 'fsize_byte': 17017448} {'fname': 'CAPITAL.MP4', 'format': 'AVC', 'width': 1280, 'height': 720, 'duration': 284.3, 'framerate': 30.0, 'fsize_byte': 26107717}
Right now I'm using for loop to iterate through list and dictionary, check for value and append to another newly created list.

Is there a better way? Do changes IN list rather than create another list.

Thanks
use list comprehension.
also possible to use filter(), but list comprehension is preferred

of course there is option to not create full list in the first place or create just a generator expression
(Sep-28-2020, 07:09 AM)buran Wrote: [ -> ]use list comprehension.

old_list = [rec for rec in old_list if rec.get('format') != 'HEVC']
Is this the correct way?
(Sep-28-2020, 08:04 AM)Denial Wrote: [ -> ]
(Sep-28-2020, 07:09 AM)buran Wrote: [ -> ]use list comprehension.

old_list = [rec for rec in old_list if rec.get('format') != 'HEVC']
Is this the correct way?

Yes, but only if you don't need the old_list.
You've overwritten the old_list with your new list.

There are often situations where you need to keep the original data and working with filters to select them.

You've also the possibility to remove an entry from your list, if you have a reference to the element inside.
first_dict = old_list[0] # getting the reference to the first element
old_list.remove(first_dict) # if first_dict is not in old_list -> ValueError
(Sep-28-2020, 08:04 AM)Denial Wrote: [ -> ]Is this the correct way?
if you need to keep the old list
new_list = [rec for rec in old_list if rec.get('format') != 'HEVC']
(Sep-28-2020, 07:05 AM)Denial Wrote: [ -> ]I want to remove all dictonaries records from the list where 'format' is not 'HEVC'.

Comprehension/generator are very good solutions but following tries to address OP 'remove records from the list' objective:

for i, record in enumerate(old_list):
    if record['format'] != 'HEVC':
        old_list.pop(i)
@perfingo - you will be surprised what the result of your code is when the order of elements is different. Don't change list while iterating over it
old_list = [                                                                        
{'fname': 'Welcome.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 118.867, 'framerate': 30.0, 'fsize_byte': 4095489},
{'fname': 'Line.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 141.8, 'framerate': 25.0, 'fsize_byte': 4495620},
{'fname': 'tut.webm', 'format': 'VP9', 'width': 1152, 'height': 720, 'duration': 535.633, 'framerate': 23.976, 'fsize_byte': 17017448},
{'fname': 'CAPITAL.MP4', 'format': 'AVC', 'width': 1280, 'height': 720, 'duration': 284.3, 'framerate': 30.0, 'fsize_byte': 26107717},
]


for i, record in enumerate(old_list):
    if record['format'] != 'HEVC':
        old_list.pop(i)

print(old_list)
Output:
[{'fname': 'Welcome.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 118.867, 'framerate': 30.0, 'fsize_byte': 4095489}, {'fname': 'Line.mp4', 'format': 'HEVC', 'width': 1920, 'height': 1080, 'duration': 141.8, 'framerate': 25.0, 'fsize_byte': 4495620}, {'fname': 'CAPITAL.MP4', 'format': 'AVC', 'width': 1280, 'height': 720, 'duration': 284.3, 'framerate': 30.0, 'fsize_byte': 26107717}]
it will work if you iterate over copy of the original list though
assigning list comprehension to old_list is solving OP of removing elements and keeping the same variable
(Sep-28-2020, 09:17 AM)buran Wrote: [ -> ]@perfingo - you will be surprised what the result of your code is when the order of elements is different. Don't change list while iterating over it
/.../
it will work if you iterate over copy of the original list though
assigning list comprehension to old_list is solving OP of removing elements and keeping the same variable

Mea culpa! What was I thinking? Through my lapse of attention I gave really bad advice and committed real sin (fortunately no puppies died). As smart people had said:

"If fact, in any programming language for most part if you mutate something while you iterating over it you living in state of sin and you deserve whatever happens to you" -- Raymond Hettinger, Python core-developer, Transforming Code into Beautiful, Idiomatic Python