a = {'spam': 1, 'eggs': 2, 'tomato': 3} b = {'spam': 4, 'bacon': 5} c = a.copy() c.update(b) print c
Monthly Archives: July 2016
Casting operators in C++
static_cast<>
const_cast<>
dynamic_cast<>
reinterpret_cast<>
- C-style casts
static_cast<>
Is for widening numeric conversions (e.g., int
to float
), converting between pointer types and void*
.
Can also be used to call explicit (or implicit) conversion functions.
Can cast around the hierarchy but it isn’t checked.
const_cast<>
Add or remove const
to a variable.
Not so important because of mutable
.
Can be used to call const
-overloaded member functions.
Can also add or remove volatile
dynamic_cast<>
For casting around hierarchies.
Will return nullptr
on failure for a pointer, or throw std::bad_cast
for references.
Can cast sideways and up other hierarchies
Doesn’t work if you have a diamond and haven’t used virtual inheritance
Only works for public inheritance
reinterpret_cast<>
Will convert anything into anything.
Use to cast a pointer to or from an opaque type, or to cast a blob of memory to a POD type
Is reversible unless you cast to a type with less storage space
C-style casts
T(object)
or (T)object
This is the same thing as a "function-style cast"
Perform the new casts in order:
const_cast
static_cast
static_cast
thenconst_cast
reinterpret_cast
reinterpret_cast
then const_cast
Note that dynamic_cast
is not in this list – you can cast around the hierarchy with C-style casts, but it isn’t checked
Calling an external command from Python
Use the subprocess module
For Python versions before 3.5:
import subprocess subprocess.call(["ls", "-l"])
For Python 3.5 and above:
import subprocess subprocess.run(["ls", "-l"])
The explicit keyword in C++
The explicit
keyword prevents the compiler from using converting constructors for implicit conversions.
Don’t forget that constructors with a single non-default argument are also converting constructors.
Ternary operator in Python
There is no ternary operator in Python, but you can do this:
myvar = a if condition else b
See Is there an equivalent of C’s ”?:” ternary operator? in the Programming FAQ.
Differences Between pointers and references in C++
- A pointer can be declared uninitialized, but a reference must be declared referring to something
- A pointer can be reassigned, but a reference cannot be reassigned – assigning to it changes the referent
- Pointers can be
NULL
, but there is no equivalent for references – they always need to refer to a valid object - You can take the address of a pointer, but you can’t take the address of a reference (you’ll get the address of the referent)
- You can make a pointer to a pointer, or a reference to a pointer, but you can’t make a reference to a reference
- You can do arithmetic with pointers, but you can’t do arithmetic with references (it would attempt to do arithmetic with the referent)
- You de-reference pointers, but you don’t de-reference references (they are automatically de-referenced)
- When you call a function that takes a pointer, you can always see at the call site that the argument is a pointer (because it’s declared as a pointer variable, or you take the address of it), but the creation of a reference by function call isn’t explicit at the call site
The yield keyword in Python
To understand how yield
works, you need to understand iterables, iterators, and generators
Iterables
An iterable is an object capable of returning its members one at a time. Iterables include:
All sequence types, such as:
list
str
tuple
Some none-sequence types, such as:
dict
- file objects
- any objects of user-defined classes with an
__iter__()
method or with a__getitem__()
method that implements Sequence
semantics (see below)
Iterables can be used in a for
loop and in many other places where a sequence is needed:
zip()
map()
When an iterable object is passed to the built-in function iter()
, it returns an iterator for the object.
The iterator is good for one pass over the set of values
It is usually not necessary to call iter()
directly, as the for
statement does this for you, creating a temporary unnamed
variable to hold the iterator for the duration of the loop.
User-defined iterables need to define one of __iter__()
or __getitem__()
.
__iter__()
Called when an iterator is required for a container.
Iterator objects also need to implement this method; they are required to return themselves.
__getitem__()
Called to implement self[key]
.
For sequence types, the accepted keys should be integers or slice objects.
The interpretation of negative slices is the responsibility of the __getitem__()
method.
If key is of the wrong type, a TypeError
may be raised.
If the key is of a value outside the set of indexes for the sequence, an IndexError
should be raised.
For mapping types, if key is missing, a KeyError
should be raised.
Iterators
An iterator is an object representing a stream of data.
Calls to the object’s __next__()
method (or passing it to the built-in function next()
) return successive items in the
stream.
When no more data are available, a StopIteration
exception is raised.
The iterator is then exhausted, and any subsequent calls to __next__()
method will raise a StopIteration
again.
Iterators are required to have an __iter__()
method so every iterator is also iterable and may be used in most places where
other iterables are accepted.
Generators
The word generator refers to two things: a generator function and a generator iterator.
Generator function
A generator function is like a normal function except that it contains one or more yield
expressions.
When a generator function is called, its code is not executed, and instead it returns a generator iterator.
Generator iterator
This is an iterator that controls the execution of the generator function in response to calls to the next()
function.
Each yield in the associated generator function causes execution to be temporarily suspended. When the iterator resumes, execution continues from where it left off.
How to split a string in C++
Java has String.split()
, Python has string.split()
, Perl has split
. There is no simple string-splitting method in C++, but there are plenty of ways of doing it. Here are some methods:
- Put it in a
stringstream
and extract the tokens - Put it in a
stringstream
and usegetline()
with a delimiter - Use
string::find
progressively - Use
string::find_first_of
progressively with a number of delimiters - Use
boost::split()
- Use
boost::split_iterator
- Use
boost::tokenizer
- Use
boost::sregex_token_iterator
- Use
pystring::split
- Use my C
split
function
1. Put it in a stringstream
and extract the tokens
#include <string> #include <sstream> #include <algorithm> #include <iterator> template <class Container> void split1(const std::string& str, Container& cont) { std::istringstream iss(str); std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(cont)); }
2. Put it in a stringstream
and use getline()
with a delimiter
#include <string> #include <sstream> #include <algorithm> #include <iterator> template <class Container> void split2(const std::string& str, Container& cont, char delim = ' ') { std::stringstream ss(str); std::string token; while (std::getline(ss, token, delim)) { cont.push_back(token); } }
3. Use string::find
progressively
#include <string> #include <algorithm> #include <iterator> template <class Container> void split3(const std::string& str, Container& cont, char delim = ' ') { std::size_t current, previous = 0; current = str.find(delim); while (current != std::string::npos) { cont.push_back(str.substr(previous, current - previous)); previous = current + 1; current = str.find(delim, previous); } cont.push_back(str.substr(previous, current - previous)); }
4. Use string::find_first_of
progressively with a number of delimiters
#include <string> #include <algorithm> #include <iterator> template <class Container> void split4(const std::string& str, Container& cont, const std::string& delims = " ") { std::size_t current, previous = 0; current = str.find_first_of(delims); while (current != std::string::npos) { cont.push_back(str.substr(previous, current - previous)); previous = current + 1; current = str.find_first_of(delims, previous); } cont.push_back(str.substr(previous, current - previous)); }
5. Use boost::split()
#include <string> #include <boost/algorithm/string.hpp> template <class Container> void split5(const std::string& str, Container& cont, const std::string& delims = " ") { boost::split(cont, str, boost::is_any_of(delims)); }
Reference: Function template split
6. Use boost::split_iterator
#include <string> #include <boost/algorithm/string.hpp> template <class Container> void split6(const std::string& str, Container& cont, char delim = ' ') { typedef boost::split_iterator<std::string::const_iterator> spliterator; std::string sdelim(1, delim); for (spliterator it = boost::make_split_iterator(str, boost::first_finder(sdelim, boost::is_equal())); it != spliterator(); ++it) { cont.push_back(boost::copy_range<std::string>(*it)); } }
Reference: Function template make_split_iterator
7. Use Use boost::tokenizer
#include <string> #include <algorithm> #include <boost/tokenizer.hpp> template <class Container> void split7(const std::string& str, Container& cont, const std::string& delims = " ") { typedef boost::char_separator<char> separator; boost::tokenizer<separator> tokens(str, separator(delims.c_str())); std::copy(tokens.begin(), tokens.end(), std::back_inserter(cont)); }
Reference: Tokenizer Class
8. Use boost::sregex_token_iterator
#include <string> #include <algorithm> #include <boost/regex.hpp> template <class Container> void split8(const std::string& str, Container& cont, const std::string delim = "\\s+") { boost::regex re(delim); std::copy(boost::sregex_token_iterator(str.begin(), str.end(), re, -1), boost::sregex_token_iterator(), std::back_inserter(cont)); }
Reference: regex_token_iterator
9. Use pystring::split()
#include <pystring.h> template <class Container> void split9(const std::string& str, Container& cont, const std::string delim = " ") { std::vector<std::string> vec; pystring::split(str, vec, delim); std::copy(vec.begin(), vec.end(), std::back_inserter(cont)); }
Reference: pystring/pystring.h
10. Use my C split function
template <class Container> void add_to_container(const char *str, size_t len, void *data) { Container *cont = static_cast<Container*>(data); cont->push_back(std::string(str, len)); } template <class Container> void split10(const std::string& str, Container& cont, char delim = ' ') { split(str.c_str(), delim, static_cast<split_fn>(add_to_container<Container>), &cont); }
Reference: Split a string in C
An example program
#include <iostream> #include <string> #include <algorithm> #include <iterator> #include <vector> int main() { char str[] = "The quick brown fox jumps over the lazy dog"; std::vector<std::string> words; split1(str, words); std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n")); }
The quick brown fox jumps over the lazy dog
Related
- How to find a substring in C++
- How to do string formatting in C++
- How to replace all occurrences of a character in a std::string
- How to do case-insensitive string comparison in C++
- How to concatenate a string and an int in C++
- How to convert a string to lower or upper case in C++
- How to trim a std::string in C++
- How to get a const char* or a char* from a std::string
- How to convert an int to a std::string in C++