Skip to content
scipython.com

P2.5.12Electronic configurations

The electron configuration of an atom is the specification of the distribution of its electrons in atomic orbitals. An atomic orbital is identified by a principal quantum number, \(n = 1,2,3,\cdots\) defining a shell comprised of one or more subshells defined by the azimuthal quantum number, \(l=0,1,2,\cdots{n-1}\). The values \(l=0,1,2,3\) are refered to be the letters \(s\), \(p\), \(d\), and \(f\) respectively. Thus, the first few orbitals are: 1s (\(n=1, l=0\)), 2s (\(n=2, l=0\)), 2p (\(n=2, l=1\)), 3s (\(n=3, l=0\)), and each shell has \(n\) subshells. A maximum of \(2(2l+1)\) electrons may occupy a given subshell.

According to the Madelung rule, the \(N\) electrons of an atom fill the orbitals in order of increasing \(n+l\) such that whenever two orbitals have the same value of \(n+l\), they are filled in order of increasing \(n\). For example, the ground state of Titanium (\(N=22\)) is predicted (and found) to be \(1s^22s^22p^63s^23p^64s^23d^2\).

Write a program to predict the electronic configurations of the elements up to Rutherfordium (\(N=104\)). The output for Titanium should be

Ti: 1s2.2s2.2p6.3s2.3p6.4s2.3d2

A Python list containing the element symbols is here: element_symbols.py

As a bonus exercise, modify your program to output the configurations using the convention that the part of the configuration corresponding to the outermost closed shell, a noble gas configuration, is replaced by the noble gas symbol in square brackets, thus:

Ti: [Ar].4s2.3d2

the configuration of Argon being 1s2.2s2.2p6.3s2.3p6.

Show solution

This program deduces the number of electrons in each atom from its position in the list, element_symbols.py.

# All element symbols up to Rf
from element_symbols import element_symbols

# Letters identifying subshells
l_letter = ['s', 'p', 'd', 'f', 'g']

def get_config_str(config):
    """ Turn a list of orbital, nelec pairs into a configuration string. """
    return '.'.join(['{:2s}{:d}'.format(*e) for e in config])

# Create and order a list of tuples, (n+l, n, l), corresponding to the order
# in which the corresponding orbitals are filled using the Madelung rule.
nl_pairs = []
for n in range(1,8):
    for l in range(n):
        nl_pairs.append((n+l, n, l))
nl_pairs.sort()

# inl indexes the subshell in the nl_pairs list; nelec is the number of
# electrons currently inhabiting this subshell
inl, nelec = 0, 0
# start with the 1s orbital
n, l = 1, 0
# a list of orbitals and the electrons they contain for a configuration
config = [['1s', 0]]
for element in element_symbols:
    nelec += 1
    if nelec > 2*(2*l+1):
        # this subshell is now full: start a new subshell
        inl += 1
        _, n, l = nl_pairs[inl]
        config.append(['{}{}'.format(n, l_letter[l]), 1])
        nelec = 1
    else:
        # add an electron to the current subshell
        config[-1][1] += 1
    # Turn config into a string and output it
    s_config = get_config_str(config)
    print('{:2s}: {}'.format(element, s_config))

Output:

H : 1s1
He: 1s2
Li: 1s2.2s1
Be: 1s2.2s2
B : 1s2.2s2.2p1
C : 1s2.2s2.2p2
N : 1s2.2s2.2p3
...

The following version of the program does some additional work to output the closed-shell part of the configuration as a noble gas element symbol:

# All element symbols up to Rf
from element_symbols import element_symbols

# Letters identifying subshells
l_letter = ['s', 'p', 'd', 'f', 'g']

def get_config_str(config):
    """ Turn a list of orbital, nelec pairs into a configuration string. """
    return '.'.join(['{:2s}{:d}'.format(*e) for e in config])

# Create and order a list of tuples, (n+l, n, l), corresponding to the order
# in which the corresponding orbitals are filled using the Madelung rule.
nl_pairs = []
for n in range(1,8):
    for l in range(n):
        nl_pairs.append((n+l, n, l))
nl_pairs.sort()

# inl indexes the subshell in the nl_pairs list; nelec is the number of
# electrons currently inhabiting this subshell
inl, nelec = 0, 0
# start with the 1s orbital
n, l = 1, 0
# a list of orbitals and the electrons they contain for a configuration
config = [['1s', 0]]
# Store the most recent Noble gas configuration encountered in a tuple with the
# corresponding element symbol
noble_gas_config = ('', '')
for i, element in enumerate(element_symbols):
    nelec += 1
    if nelec > 2*(2*l+1):
        # this subshell is now full
        if l == 1:
            # The most recent configuration was for a Noble gas: store it
            noble_gas_config = (get_config_str(config),
                                '[{}]'.format(element_symbols[i-1]))
        # Start a new subshell
        inl += 1
        _, n, l = nl_pairs[inl]
        config.append(['{}{}'.format(n, l_letter[l]), 1])
        nelec = 1
    else:
        # add an electron to the current subshell
        config[-1][1] += 1
    # Turn config into a string
    s_config = get_config_str(config)
    # Replace the heaviest Noble gas configuration with its symbol
    s_config = s_config.replace(*noble_gas_config)
    print('{:2s}: {}'.format(element, s_config))

Hence:

...
Md: [Rn].7s2.5f13
No: [Rn].7s2.5f14
Lr: [Rn].7s2.5f14.6d1
Rf: [Rn].7s2.5f14.6d2