re.search() if result is None
<p>How to make this pythonic?</p>

<pre><code>def money_from_string(s):
    gold = re.search("([0-9]+)g", s)
    silver = re.search("([0-9]+)s", s)
    copper = re.search("([0-9]+)c", s)
    s = re.sub("[0-9]+g", "", s)
    s = re.sub("[0-9]+s", "", s)
    s = re.sub("[0-9]+c", "", s)
    assert (len(s.strip()) == 0) # should be 0

    return (gold.group() or 0) * 10000 + (silver.group() or 0) * 100 + (copper.group() or 0)
</code></pre>

<p>This doesn't work because if <code>gold</code> is <code>None</code>, <code>gold.group()</code> will throw an error.</p>

<p>Input examples &amp; expected outputs:</p>

<pre><code>s = "15g17s5c" -&gt; 150000 + 1700 + 5 -&gt; 151705
s = "15g5s"    -&gt; 150000 + 500      -&gt; 150500
s = "15g"      -&gt; 150000            -&gt; 150000
s = "17s5c"    -&gt; 1700 + 5          -&gt; 1705
s = "5c"       -&gt; 5                 -&gt; 5
</code></pre>

<p>Note that I do appropriate checks on the input, to ensure that it actually is of correct format. Ie. it has match:</p>

<pre><code>MONEY_PATTERNS = [
    "([0-9]+g[ ]*[0-9]+s[ ]*[0-9]+c)", # g / s / c
    "([0-9]+g[ ]*[0-9]+s)", # g / s
    "([0-9]+g[ ]*[0-9]+c)", # g / c
    "([0-9]+s[ ]*[0-9]+c)", # s / c
    "([0-9]+g)", # g
    "([0-9]+s)", # s
    "([0-9]+c)", # c
]
</code></pre>

<p>Here is how I would implement your program.</p>

<p>Note:</p>

<ul>
<li>You must use <code>int()</code> to convert strings to integers</li>
<li>I would separate the validation from the computation, but use the same regular expression in both cases.</li>
<li>I would use a dictionary, not code, to hold the values of metals.</li>
<li>By using a character class for the metal, I only have to call <code>re.findall()</code> once. </li>
<li>My regular expression allows for a richer set of inventory strings, for example <code>"10g 10g 10g"</code> represents 30 gold pieces.</li>
</ul>

<p>&nbsp;</p>

<pre><code>import re

money_from_string_pattern = re.compile(r"(\d+)([gsc])")


def is_money_from_string_valid(s):
    return not money_from_string_pattern.sub("", s).strip()


def money_from_string(s):
    value = {'g': 10000, 's': 100, 'c': 1}
    inventory = money_from_string_pattern.findall(s)
    return sum(int(amount) * value[metal] for amount, metal in inventory)

assert money_from_string("11g 22s 33c") == 112233
assert money_from_string("11g") == 110000
assert money_from_string("11g 11g") == 220000

assert is_money_from_string_valid("11g 22s 33c") == True
assert is_money_from_string_valid("11g") == True
assert is_money_from_string_valid("11g 11g") == True

assert is_money_from_string_valid("11 g 22s 33c") == False
assert is_money_from_string_valid("11g 22q") == False
assert is_money_from_string_valid("stackoverflow.com") == False
</code></pre>

python