Hi,
Trying to work out how to use a returned value to make a new dynamic variable name:
returned value equals: 'Red' which is coming from another variable named {colour}.
new variable name created equals: 'Red' + '_dom' = Red_dom
I read about global() and local() but not sure if they are the correct approach.
When I try 'Red' + '_dom' I get a string error returned by system.
I will actually need something like {colour} + '_dom' to be the new variable name as {colour} changes within a loop.
Regards,
Craig
Solved! Go to Solution.
That sort of hackery is not very pythonic. What you want is called a dictionary.
colours = {}
colour = "red"
colours[f"{colour}_dom"] = "anothervalue"
print(list(colours.keys()))
# ['red_dom']
You can use __getattr__() and __setattr__() built in methods on global/local namespaces to get/set variables by string name on an object or module.
See: https://docs.python.org/3.7/library/functions.html#getattr and https://docs.python.org/3.7/library/functions.html#setattr
That sort of hackery is not very pythonic. What you want is called a dictionary.
colours = {}
colour = "red"
colours[f"{colour}_dom"] = "anothervalue"
print(list(colours.keys()))
# ['red_dom']
If
print(colours[f"{colour}_dom"]) returns
anothervalue
and
print(colours) returns
{'red_dom': 'anothervalue'}
How do return as 'red_dom' = 'anothervalue', so from my loop I can list the variable 'red_dom' etc. to equal the returned value such as:
'Name', 'Car', 'red_dom', 'blue_dom, 'green_dom'
where 'red_dom', 'blue_dom, 'green_dom' are calculated number of coloured cars for example.
Your use case is a bit unclear to me Craig, could you add a bit of pseudo-code to try and illustrate what you're trying to do?
But if what I think you're trying to do is correct, the following might help...?
# Just some simple dummy data,
# you could have a car class or pandas dataframe with car colour, make, model, etc... details
cars = ["red", "red", "blue", "white", "white", "red", "blue", "white"]
car_colours = {}
for colour in cars:
car_colours[colour] = car_colours.get(colour, 0) + 1
# could also use
try:
car_colours[colour] += 1
except KeyError:
car_colours[colour] = 1
# Now show all colours and how many cars were that colour
for colour, count in car_colours.items():
print(f"There were {count} {colour} cars.")
# Now just print how many red and orange cars:
print(f"There were {car_colours['red']} red cars.")
print(f"There were {car_colours.get('orange', 0)} orange cars.")
# I use .get instead of ["key"] as I know there's no orange cars and would otherwise get a KeyError
Output:
There were 6 red cars.
There were 4 blue cars.
There were 6 white cars.
There were 6 red cars.
There were 0 orange cars.
Hi Luke,
Here is the type of outcome I am after (not actual data but similar scenario):
I have a large table of data (let's say car sales by dealer). I have done the stats to work out which vehicle type and style was sold in each colour. I know which is the maximum or dominant colour, and I am trying to capture that into a CSV document based on a ranking of colour.
In the script you have been addressing, I am trying to capture the dominant colour under each vehicle style so that my CSV output 'write' is something like:
csv_data = dealer, car, sedan_dom, wagon_dom, convertible_dom
Section of my script that I am trying to capture final value of sedan_dom, wagon_dom and convertible_dom.
if sorted_output[0][1] == '0': (captures null/zero tuples)
dom = '0'
else:
most_significant_output = sorted_output[0] (captures ranked dominant tuple)
dom = most_significant_output[0] (section where I need a variable in the loop to be named sedan_dom, wagon_dom, convertible_dom)
Hope that might clear up what I am attempting to do. Might have just made it more confusing.
You don't need "variable" variable names. Just rename the columns before you write out to CSV.
e.g.
columns = ["sedan", "wagon", "convertible"]
new_columns = [f"{c}_dom" for c in columns]
Here's a pandas version:
import pandas as pd
from io import StringIO # not required if reading csv from file
# Dummy csv to demo, can also read from csv file
csv = """dealer,car,sedan,wagon,convertible, junk
A,Ford,Red,0,Green, None
A,GMC,Blue,Red,0, None
B,BMW,Green,0,Red, None
B,Ford,0,Blue,Red, None
C,BMW,0,Green,0, None
C,GMC,Red,Blue,Red, None
D,GMC,Red,Blue,Blue, None
D,GMC,Red,Blue,0, None
"""
columns = ["sedan", "wagon", "convertible"] # ignore the junk etc, columns that aren't of interest
dom_columns = {c: f"{c}_dom" for c in columns}
df = pd.read_csv(StringIO(csv)) # or df = pd.read_csv(r"path/to/csv")
dom_df = df[columns].mode().rename(columns=dom_columns)
dom_df.to_csv("dom.csv", index=False)