[PYTHON] When incrementing the value of a key that does not exist

Good evening: whale2: What should I do with a sample that writes a process such as dictionary [key] + = 1 in each language and a language that displays a message such as" There is no such key "in that process? (Difficult to convey)

environment

The execution environment is as follows.

environment


#Computer
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.1
BuildVersion:	16B2555

# Ruby
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]

# Perl
$ perl -v | grep v5
This is perl 5, version 24, subversion 0 (v5.24.0) built for darwin-thread-multi-2level

# Perl6
$ perl6 -v
This is Rakudo version 2016.07.1 built on MoarVM version 2016.07
implementing Perl 6.c.

# Python
$ python --version
Python 3.5.1 :: Anaconda 4.1.0 (x86_64)

# PHP5
$ php -v
PHP 5.6.25 (cli) (built: Sep  6 2016 16:37:16)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

Ruby

Error pattern

error


target = %w[a a b b c 0 1 1 1]
count = {}

target.each{|var|
  count[ var ] += 1
}

puts count
=begin
#=>error
inc.rb:5:in `block in <main>': undefined method `+' for nil:NilClass (NoMethodError)
	from inc.rb:4:in `each'
	from inc.rb:4:in `<main>'
=end
Workaround

Ruby is beautiful.

inc.rb


target = %w[a a b b c 0 1 1 1]
count = Hash.new(0) #Set initial value

target.each{|var|
  count[ var ] += 1
}

puts count #=> {"a"=>2, "b"=>2, "c"=>1, "0"=>1, "1"=>3}

inc2.rb


target = %w[a a b b c 0 1 1 1]
count = {}
count.default = 0 #Set initial value

target.each{|var|
  count[ var ] += 1
}

puts count #=> {"a"=>2, "b"=>2, "c"=>1, "0"=>1, "1"=>3}

Python

Error pattern

error


target = 'a a b b c 0 1 1 1'.split(' ')
count = {}

for var in target:
    count[ var ] += 1

print( count )
'''
#=>error
Traceback (most recent call last):
  File "inc.py", line 6, in <module>
    count[ var ] += 1
KeyError: 'a'
'''
Workaround 1

Python seems to have a better way.

inc.py


target = 'a a b b c 0 1 1 1'.split(' ')
count = {}

for var in target:
    count.setdefault( var, 0 )
    count[ var ] += 1

print( count ) #=> {'a': 2, '1': 3, '0': 1, 'c': 1, 'b': 2}
Workaround 2

How to use defaultdict (). @Mpyw told me in the comments.

Python::inc2.py


from collections import defaultdict

target = 'a a b b c 0 1 1 1'.split(' ')
count = defaultdict(int)

for var in target:
    count[ var ] += 1

print( count ) #=> defaultdict(<class 'int'>, {'b': 2, '1': 3, '0': 1, 'a': 2, 'c': 1})
Workaround 3

How to write exception handling. It seems to be applicable to any language. Nice.

inc3.py


target = 'a a b b c 0 1 1 1'.split(' ')
count = {}

for var in target:
    try:
        count[ var ] += 1
    except KeyError:
        count[ var ] = 1

print( count )

PHP

Error pattern

I get an Undefined index Notice message, although it is not an error. ~~ ʻerror_reporting (-1);` must be written ~~

Notice


<?php
error_reporting( -1 );

$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];

foreach( $target as $var ){
  $count[ $var ] += 1;
}

echo json_encode( $count ) . PHP_EOL ;
/*
#=>
Notice: Undefined index: a in /Users/yuhei/inc.php on line 8

Notice: Undefined index: b in /Users/yuhei/inc.php on line 8

Notice: Undefined index: c in /Users/yuhei/inc.php on line 8

Notice: Undefined offset: 0 in /Users/yuhei/inc.php on line 8

Notice: Undefined offset: 1 in /Users/yuhei/inc.php on line 8
{"a":2,"b":2,"c":1,"0":1,"1":3}
*/
Workaround 1 (deprecated)

Do not suppress the error (commandment)

not recommended


<?php
error_reporting( -1 );

$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];

foreach( $target as $var ){
  @$count[ $var ] += 1; #Error suppression
}

echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
Workaround 2

Substitute 1 if there is no key. Added a conditional branch.

isset()


<?php
error_reporting( -1 );

$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];

foreach( $target as $var ){
  if( isset( $count[ $var ] ) ){
    $count[ $var ] += 1;
  }
  else{
    $count[ $var ] = 1;
  }
}

echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
Workaround 3

For this example, I think the built-in function ʻarray_count_values ()` is good.

array_count_values()


<?php
error_reporting( -1 );

$target = explode(' ', 'a a b b c 0 1 1 1');

$count = array_count_values( $target );

echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
Remarks

ʻAssign 1 if there is no key in array_count_values ()`. Increment if there is a key. It seems that the process is being performed. (It's also nice to check that the key is a number or a string)

C:php-5.6.27/ext/standard/array.c


/* {{{ proto array array_count_values(array input)
   Return the value as key and the frequency of that value in input as value */
PHP_FUNCTION(array_count_values)
{
        zval    *input,                 /* Input array */
                        **entry,                /* An entry in the input array */
                        **tmp;
        HashTable *myht;
        HashPosition pos;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) {
                return;
        }

        /* Initialize return array */
        array_init(return_value);

        /* Go through input array and add values to the return array */
        myht = Z_ARRVAL_P(input);
        zend_hash_internal_pointer_reset_ex(myht, &pos);
        while (zend_hash_get_current_data_ex(myht, (void **)&entry, &pos) == SUCCESS) {
                if (Z_TYPE_PP(entry) == IS_LONG) {
                        if (zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), (void **)&tmp) == FAILURE) {
                                zval *data;
                                MAKE_STD_ZVAL(data);
                                ZVAL_LONG(data, 1);
                                zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);
                        } else {
                                Z_LVAL_PP(tmp)++;
                        }
                } else if (Z_TYPE_PP(entry) == IS_STRING) {
                        if (zend_symtable_find(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, (void**)&tmp) == FAILURE) {
                                zval *data;
                                MAKE_STD_ZVAL(data);
                                ZVAL_LONG(data, 1);
                                zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL);
                        } else {
                                Z_LVAL_PP(tmp)++;
                        }
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!");
                }

                zend_hash_move_forward_ex(myht, &pos);
        }
}
/* }}} */

Perl Perl is the best without error.

inc.pl


use v5.24;
use warnings;
use Data::Dumper;

my @target = qw[a a b b c 0 1 1 1];
my %count;

for my $var ( @target ){
  $count{ $var } += 1;
}

print Dumper \%count;
__DATA__
#=>
$VAR1 = {
          'c' => 1,
          '1' => 3,
          'b' => 2,
          'a' => 2,
          '0' => 1
        };

Perl6 Perl 6 best (ry) that does not cause an error

inc.pl6


use v6;

my @target = <a a b b c 0 1 1 1>;
my %count;

for @target -> Str $var {
  %count{ $var } += 1;
}

%count.say; #=> {0 => 1, 1 => 3, a => 2, b => 2, c => 1}

end

Stabbed by people in each language: whale2:

References and annotations

Recommended Posts

When incrementing the value of a key that does not exist
Processing when the key input of Python pygame does not go well.
Grep so that grep does not appear at the time of grep
How to create a new file when the specified file does not exist — write if the file exists
When a character string of a certain series is in the Key of the dictionary, the character string is converted to the Value of the dictionary.
The story of the release work of the application that Google does not tell
Addictive note: max (max (list)) must not be used when maxing the value of a 2D array
An error that does not work as expected when calling the tkinter module in a text editor
The value of pyTorch torch.var () is not distributed
It is said that libmysqlclient.so.18 does not exist
python Boolean operation does not return a Boolean value
Example of what to do when the sample script does not work (OpenCV-Python)
It seems that the version of pyflakes is not the latest when flake8 is installed
About the problem that the python version of Google App Engine does not mesh
Solution to the problem that build does not end when installing OpenCV (PEP517)
EOFError: EOF when reading a line does not have a standard input value set
[Discode Bot] I created a bot that tells me the race value of Pokemon
A story that reduces the effort of operation / maintenance
[Python] A program that counts the number of valleys
Get the value of a specific key in a list from the dictionary type in the list with Python
Key input that does not wait for key input in Python
Be careful when differentiating the eigenvectors of a matrix
Solution when Linux does not recognize the built-in camera
Make a BOT that shortens the URL of Discord
Deep Learning! The story of the data itself that is read when it does not follow after handwritten number recognition
# Function that returns the character code of a string
The return value (generator) of a function that combines finally and yield must not be passed directly to next
Check when the version does not switch with pyenv
Generate that shape of the bottom of a PET bottle
There is a pattern that the program did not stop when using Python threading
The story that the return value of tape.gradient () was None
A story that analyzed the delivery of Nico Nama.
[Python] A program that compares the positions of kangaroos.
The value of meta when specifying a function with no return value in Dask dataframe apply
Get the value of a specific key up to the specified index in the dictionary list in Python
About the matter that nosetests does not pass when __init__.py is created in the project directory
About the contents of wscript when building a D language environment like that with Waf
A story that pyenv is stuck because the python execution command PATH does not pass
A tool that automatically turns the gacha of a social game
Code that sets the default value in case of AttributeError
Find the index of the maximum value (minimum value) of a multidimensional array
A program that just presses and releases the Esc key
Check when the Docker container does not connect to the Internet
Extract the value of dict or list as a string
A Python script that compares the contents of two directories
I want to output while converting the value of the type (e.g. datetime) that is not supported when outputting json with python
I implemented a method to calculate the evaluation index (specificity, NPV) that scikit-learn does not have
A decorator that notifies you via AWS-SNS if the function does not finish within the specified time
A memo that reproduces the slide show (gadget) of Windows 7 on Windows 10.
The story that the version of python 3.7.7 was not adapted to Heroku
pandas Fetch the name of a column that contains a specific character
Find the optimal value of a function with a genetic algorithm (Part 2)
The story that a hash error came out when using Pipenv
A formula that simply calculates the age from the date of birth
A story that struggled to handle the Python package of PocketSphinx
Explaining the mechanism of Linux that you do not know unexpectedly
Solution when background-cover of Linux version VS Code does not work
A function that measures the processing time of a method in python
How to find the memory address of a Pandas dataframe value
The story of creating a site that lists the release dates of books
The problem that the version of Vue CLI did not go up