Asked  7 Months ago    Answers:  5   Viewed   37 times

What's the best way, both aesthetically and from a performance perspective, to split a list of items into multiple lists based on a conditional? The equivalent of:

good = [x for x in mylist if x in goodvals]
bad  = [x for x in mylist if x not in goodvals]

is there a more elegant way to do this?

Update: here's the actual use case, to better explain what I'm trying to do:

# files looks like: [ ('file1.jpg', 33L, '.jpg'), ('file2.avi', 999L, '.avi'), ... ]
IMAGE_TYPES = ('.jpg','.jpeg','.gif','.bmp','.png')
images = [f for f in files if f[2].lower() in IMAGE_TYPES]
anims  = [f for f in files if f[2].lower() not in IMAGE_TYPES]

 Answers

17
good = [x for x in mylist if x in goodvals]
bad  = [x for x in mylist if x not in goodvals]

is there a more elegant way to do this?

That code is perfectly readable, and extremely clear!

# files looks like: [ ('file1.jpg', 33L, '.jpg'), ('file2.avi', 999L, '.avi'), ... ]
IMAGE_TYPES = ('.jpg','.jpeg','.gif','.bmp','.png')
images = [f for f in files if f[2].lower() in IMAGE_TYPES]
anims  = [f for f in files if f[2].lower() not in IMAGE_TYPES]

Again, this is fine!

There might be slight performance improvements using sets, but it's a trivial difference, and I find the list comprehension far easier to read, and you don't have to worry about the order being messed up, duplicates being removed as so on.

In fact, I may go another step "backward", and just use a simple for loop:

images, anims = [], []

for f in files:
    if f.lower() in IMAGE_TYPES:
        images.append(f)
    else:
        anims.append(f)

The a list-comprehension or using set() is fine until you need to add some other check or another bit of logic - say you want to remove all 0-byte jpeg's, you just add something like..

if f[1] == 0:
    continue
Tuesday, June 1, 2021
 
PLPeeters
answered 7 Months ago
27

python3 is not Python syntax, it is the Python binary itself, the thing you run to get to the interactive interpreter.

You are confusing the command line with the Python prompt. Open a console (Windows) or terminal (Linux, Mac), the same place you'd use dir or ls to explore your filesystem from the command line.

If you are typing at a >>> or In [number]: prompt you are in the wrong place, that's the Python interpreter itself and it only takes Python syntax. If you started the Python prompt from a command line, exit at this point and go back to the command line. If you started the interpreter from IDLE or in an IDE, then you need to open a terminal or console as a separate program.

Other programs that people often confuse for Python syntax; each of these is actually a program to run in your command prompt:

  • python, python2.7, python3.5, etc.
  • pip or pip3
  • virtualenv
  • ipython
  • easy_install
  • django-admin
  • conda
  • flask
  • scrapy
  • setup.py -- this is a script you need to run with python setup.py [...].
  • Any of the above together with sudo.

with many more variations possible depending on what tools and libraries you have installed and what you are trying to do.

If given arguments, you'll get a SyntaxError exception instead, but the underlying cause is the same:

>>> pip install foobar
  File "<stdin>", line 1
    pip install foobar
              ^
SyntaxError: invalid syntax
Tuesday, June 1, 2021
 
QuantumMechanic
answered 7 Months ago
44

I would use a generator:

def group(seq, sep):
    g = []
    for el in seq:
        if el == sep:
            yield g
            g = []
        g.append(el)
    yield g

ex = ['A', 'WORD', 'B' , 'C' , 'WORD' , 'D']
result = list(group(ex, 'WORD'))
print(result)

This prints

[['A'], ['WORD', 'B', 'C'], ['WORD', 'D']]

The code accepts any iterable, and produces an iterable (which you don't have to flatten into a list if you don't want to).

Tuesday, June 8, 2021
 
akohout
answered 7 Months ago
58

use the following to convert to a timestamp in python 2

int((mod_time.mktime(first_run.timetuple())+first_run.microsecond/1000000.0))

Sunday, August 22, 2021
 
waylaidwanderer
answered 4 Months ago
100

How about this?

points[[
    Flatten[Position[clusterIndices, #]]
    ]] & /@
 Union[clusterIndices]
Sunday, October 3, 2021
 
Elio Campitelli
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share