In shell, you don't put a $ in front of a variable you're assigning. You only use $IP when you're referring to the variable.
#!/bin/bash IP=$(curl automation.whatismyip.com/n09230945.asp) echo "$IP" sed "s/IP/$IP/" nsupdate.txt | nsupdate
ID : 20272
viewed : 18
94
In shell, you don't put a $ in front of a variable you're assigning. You only use $IP when you're referring to the variable.
#!/bin/bash IP=$(curl automation.whatismyip.com/n09230945.asp) echo "$IP" sed "s/IP/$IP/" nsupdate.txt | nsupdate
89
Same with something more complex...getting the ec2 instance region from within the instance.
INSTANCE_REGION=$(curl -s 'http://169.254.169.254/latest/dynamic/instance-identity/document' | python -c "import sys, json; print json.load(sys.stdin)['region']") echo $INSTANCE_REGION
70
In case you have different conditions to evaluate for keys and values, @Marcin's answer is the way to go.
If you have the same condition for keys and values, you're better off with building (key, value)-tuples in a generator-expression feeding into dict()
:
dict((modify_k(k), modify_v(v)) if condition else (k, v) for k, v in dct.items())
It's easier to read and the condition is only evaluated once per key, value.
Example with borrowing @Cleb's dictionary of sets:
d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}
Assume you want to suffix only keys
with a
in its value
and you want the value
replaced with the length of the set in such a case. Otherwise, the key-value pair should stay unchanged.
dict((f"{k}_a", len(v)) if "a" in v else (k, v) for k, v in d.items()) # {'key1_a': 3, 'key2': {'bar', 'foo'}, 'key3': {'sad', 'so'}}
63
It also might be worth mentioning that If only statements put the if at the end:
{_ for _ in iterable if True}
53
Another example in using if/else in dictionary comprehension
I am working on data-entry desktop application for my own office work, and it is common for such data-entry application to get all entries from input widget and dump it into a dictionary for further processing like validation, or editing which we must return selected data from file back to entry widgets, etc.
The first round using traditional coding (8 lines):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}} a_dic, b_dic = {}, {} for field, value in entries.items(): if field == 'ther': for k,v in value.items(): b_dic[k] = v a_dic[field] = b_dic else: a_dic[field] = value print(a_dic) “ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
Second round I tried to use dictionary comprehension but the loop still there (6 lines):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}} for field, value in entries.items(): if field == 'ther': b_dic = {k:v for k,v in value.items()} a_dic[field] = b_dic else: a_dic[field] = value print(a_dic) “ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
Finally, with a one-line dictionary comprehension statement (1 line):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}} a_dic = {field:{k:v for k,v in value.items()} if field == 'ther' else value for field, value in entries.items()} print(a_dic) “ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
I use python 3.8.3