Dictionaries are Python implementations of hash tables. They store arbitrary key-value associations, not restricted to a single data type. The dictionaries do not preserve order (no order between elements is defined) so there is no guarantee that any element enumeration will yield a certain order.
NB: unless otherwise specified, everything is Python 2 syntax.
Defining a dictionary:
D = { }
Initializing a dictionary:
D = dict( (i, False) for i in xrange(1, 11) if i % 2 == 0 ) #Python 2 D = { i : False for i in range(1, 11) if i % 2 == 0 } #Python 3
Note: this syntax is also known as dictionary comprehension.
Enumerating all the items in a dictionary:
for i in D: print i, D[i] #key, value
…or:
for k, v in D.iteritems(): print k, v #key, value
Looking up an element:
if k in D: print k
Adding elements:
D[key] = value
Note: no error is thrown if the element already exists; an overwrite happens.
Removing elements:
del D[key]
Using a dictionary as a lookup table to remove duplicates in a list:
D = {} for i in L: if i in D: del L[i] else: D[i] = True
Note: a set data type is more suited for such task. There is also a simplified syntax (e.g. list(set(L)) ) that can be used if the element order within the input list does not need to be preserved.
That’s it for today, thank you for your read!
Lists are linear sequences that provide constant time data lookup. They can be resized, searched, sorted (using a custom compare function) and are not restricted to a single data type (e.g. you can define lists with mixed data). Lists in Python are 0 indexed.
Defining a pre-initialized list with 10 numeric values (all zeros):
A = [0] * 10
Defining a pre-initialized list with 10 numeric values (powers of 2):
A = [ 2**i for i in xrange(0, 10) ]
Note1: xrange above returns values from 0 to 9 inclusive.
Note2: this syntax is known as list comprehension.
Iterating through all the elements (read only):
A = [ 0, 'a', {'b':'c'} ] for e in A: print e
Iterating through all the elements (read/write):
A = [ 0, 'a', {'b':'c'} ] for i in xrange(len(A)): print i, A[i]
Adding new elements at the end of the list:
A = [ 0, 1, 2, 3 ] A += [ 4 ]
Note: there is an append method that can also be used for this purpose.
Insert new elements:
A = [ 0, 1, 2, 3 ] A.insert(0, -1) #position, value
Note: the insert above puts a new element at the front of the list.
Find elements in the list:
A = [ 0, 1, 2, 3 ] A.index(2)
Note: index does a linear search for the element with the value provided. A ValueError exception is thrown if the element cannot be found.
Remove elements from the list:
A = [ 0, 1, 2, 3 ] A.remove(2) #by value del A[1] #by index
Using a Python List as a Stack:
A = [ ] A.append(1) A.append(2) #always add elements at the end stacktop = A.pop() #returns 2, the last element added
Note: pop throws the exception IndexError if the list is empty.
Using a Python List as a Queue:
A = [ ] A.insert(0, 1) A.insert(0, 2) #always insert at the beginning of the list elem = A.pop() #returns 1, the first element added
Note: for an optimized implementation for both Stacks and Queues you may want to look at the collections.deque data structure.
That’s it for today, have fun!

There is no such thing as a completely secure server: as long as you provide public access to services running on a server, there is a risk that somebody at some point is going to try something like a privilege escalation or denial of service. What one can do is to minimize the chance of success of such attack or at least to minimize the damages.
I am not going to provide here some “high tech” security mechanisms but rather some “common sense” ones; such measures will most likely prevent speculative attackers or bots from doing their stuff. Let’s start with the first trick from the book:
1. Set up iptables
One may think: why set the firewall up? If I provide 3 services to the world and those are the only ones with listening sockets, why would I need a completely configured firewall?
The answer is: the firewall is always necessary. Having a policy of “deny all + exceptions” will render useless any rogue service that an attacker may inject through some privilege escalation attack.
On a RedHat (CentOS) system one will find the firewall configuration file as /etc/sysconfig/iptables. A typical restrictive configuration might be:
*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
The configuration above allows new tcp traffic (new connections) to ports 22 (ssh), 80 (http) and 443 (https), while allowing all outgoing traffic and also the responses received in relation to such traffic. It also allows icmp (ping), but denies everything else.