#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2005
    Posts
    54
    Rep Power
    10

    Confused about Boolean truth values of dictionaries


    I want to write a script that lists each item seen in a file just once. For example, I could have a file that lists the manufacturers and models of a whole bunch of cars, and I want to make a list of manufacturers. So if I've already seen, e.g., 'Honda' and added it to the list, I don't want to do so again. In perl I would do this with a hash, e.g. %car_seen, and then I could say:

    Code:
    my %car_seen = ();
    my @cars = ();
    car = "Honda";
    if ($car_seen{$car}) {
        print "already saw $car\n";
    } else {
        push (@cars, $car);
        $car_seen{$car} = 1;
    }
    In Python, I don't seem to be able to do the same thing with a dictionary. The following doesn't work:

    Code:
    car_seen = {}
    cars = []
    car = 'Honda'
    if car_seen[car]:
        print('already saw this')
    else:
        cars.append(car)
        car_seen[car] = 1
    However, if I set car_seen to 1, then things work as I expect:

    Code:
    car_seen = {}
    cars = []
    car = 'Honda'
    car_seen[car] = 1
    if car_seen[car]:
        print('already saw this')
    else:
        cars.append(car)
        car_seen[car] = 1
    This prints 'already saw this', exactly as I would expect. Why doesn't my first Python example treat 'car_seen[car]' as false, since it doesn't exist, and then append car to the list cars?

    Thank you.

    Eric
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2007
    Location
    Joensuu, Finland
    Posts
    438
    Rep Power
    67
    Originally Posted by EJF
    In Python, I don't seem to be able to do the same thing with a dictionary. The following doesn't work:

    Code:
    car_seen = {}
    cars = []
    car = 'Honda'
    if car_seen[car]:
        print('already saw this')
    else:
        cars.append(car)
        car_seen[car] = 1
    “car_seen[car]” returns the value of the given key (instead of checking whether the key exists at all). What you want is:

    Code:
    if car in car_seen:
    But actually, if you are not counting the cars but only checking whether you’ve seen them, you’d be better off using sets:

    Code:
    cars = set()
    # ...
    cars.add(car) # doesn’t require “if” since elements are unique

    Comments on this post

    • Lux Perpetua agrees
    Last edited by SuperOscar; January 9th, 2013 at 02:29 AM.
    My armada: openSUSE 13.1 (home desktop, home laptop), Crunchbang Linux 11 (work laptop), Trisquel GNU/Linux 6.0.1 (mini laptop), Ubuntu 14.04 LTS (server), Android 4.2.1 (tablet), Windows 7 Ultimate (testbed)
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2005
    Posts
    54
    Rep Power
    10
    Originally Posted by SuperOscar
    “car_seen[car]” returns the value of the given key (instead of checking whether the key exists at all). What you want is:

    Code:
    if car in car_seen:
    But actually, if you are not counting the cars but only checking whether you’ve seen them, you’d be better off using sets:

    Code:
    cars = set()
    # ...
    cars.add(car) # doesn’t require “if” since elements are unique
    Thanks so much. That's extremely helpful.

    Best wishes,

    Eric

IMN logo majestic logo threadwatch logo seochat tools logo