Reputation: 11
So I'm making this function to tell me what the type of a variable is along with the variable because of random curiosity and I have it so it indents lines for each item that is contained within a list/dictionary/tuple after telling you it's a list/dictionary/tuple like
list: string: words integer: 123
and since Python lets you put other lists inside lists and stuff I wanna be able to call the function recursively to make it so inside lists get an additional indent like
list: string: words list: string: more words integer 456 integer 123 but when I call the function recursively it messes that up. I was thinking I might be able to do it using
end="stuff"
after the strings but haven't figured out a way to get that to work right.
Also when I call the function within a dictionary item using a for loop it weirdly loses the string text I had around it that was supposed to specify if the part being printed there was a key or value and I have no idea why since it's inside a for loop so for every new key-value pair it should do the print statement all over, instead, it only puts the print statement with that follows this for key 'None' : value 'None'
where the None doesn't actually belong to anything in the dictionary.
Here's my code Heres my code
def print_type_and_value_for_variable(i):
if type(i) is str:
print(f"string: {i}")
elif type(i) is int:
print(f"integer: {i}")
elif type(i) is float:
print(f"float: {i}")
elif type(i) is list:
print("list:")
for j in i:
print(f" {j}")
elif type(i) is dict:
print("dictionary:")
for key, value in i.items():
# print(f" key '{key}' : value"
# f" '{value}'")
print(f" key '{print_type_and_value_for_variable(key)}' : value"
f" '{print_type_and_value_for_variable(value)}'")
elif type(i) is tuple:
print("tuple:")
for j in i:
print(f" {j}")
elif type(i) is bool:
print(f"boolean: {i}")
elif type(i) is set:
print("set:")
for j in i:
print(f" {j}")
elif type(i) is frozenset:
print("frozen set:")
for j in i:
print(f" {j}")
elif type(i) is complex:
print(f"complex: {i}")
elif type(i) is range:
print(f"range: {i}")
elif type(i) is None:
print(f"none {i}")
elif type(i) is bytes:
print(f"bytes: {i}")
elif type(i) is bytearray:
print(f"byte array: {i}")
elif type(i) is memoryview:
print(f"memory view: {i}")
else:
print(f"unknown variable type {type(i)}: {i}")
# print()
list_of_stuff = [1,
2,
"words",
["inner",
"list"
],
{1: "one",
2: "two",
"3": [3.1, 3.2, 3.3]
},
"words 2",
0.314
]
for item in list_of_stuff:
print_type_and_value_for_variable(item)
and here's the output I get from it
integer: 1
integer: 2
string: words
list:
inner
list
dictionary:
integer: 1
string: one
key 'None' : value 'None'
integer: 2
string: two
key 'None' : value 'None'
string: 3
list:
3.1
3.2
3.3
key 'None' : value 'None'
string: words 2
float: 0.314
Everything under dictionary:
and above string: words 2
should be indented one more time. Please help.
Upvotes: 1
Views: 52
Reputation: 35636
You can pass an additional parameter to your function called indent which defaults to 0. Each time you recur you can increase this variable by 1. Since a default is provided, you don't need to pass any parameter at all, which allows you to use the function as you have been without modification, or you can specify a starting indent.
Then at the beginning of each call print out the necessary spacing. 0 * '\t'
will be the empty string and not affect the indentation of any calls where indent is 0.
def print_type_and_value_for_variable(i, indent=0):
print(indent * '\t', end='')
if type(i) is str:
print(f"string: {i}")
elif type(i) is int:
print(f"integer: {i}")
elif type(i) is float:
print(f"float: {i}")
elif type(i) is list:
print("list:")
for j in i:
print_type_and_value_for_variable(j, indent + 1)
elif type(i) is dict:
print("dictionary:")
for key, value in i.items():
print(f" key '{print_type_and_value_for_variable(key, indent + 1)}' : value"
f" '{print_type_and_value_for_variable(value, indent + 1)}'")
elif type(i) is tuple:
print("tuple:")
for j in i:
print(f" {j}")
elif type(i) is bool:
print(f"boolean: {i}")
elif type(i) is set:
print("set:")
for j in i:
print(f" {j}")
elif type(i) is frozenset:
print("frozen set:")
for j in i:
print(f" {j}")
elif type(i) is complex:
print(f"complex: {i}")
elif type(i) is range:
print(f"range: {i}")
elif type(i) is None:
print(f"none {i}")
elif type(i) is bytes:
print(f"bytes: {i}")
elif type(i) is bytearray:
print(f"byte array: {i}")
elif type(i) is memoryview:
print(f"memory view: {i}")
else:
print(f"unknown variable type {type(i)}: {i}")
list_of_stuff = [1,
2,
"words",
["inner",
"list"
],
{1: "one",
2: "two",
"3": [3.1, 3.2, 3.3],
4: {1: "test", 2: "test2"}
},
"words 2",
0.314
]
for item in list_of_stuff:
print_type_and_value_for_variable(item)
You might consider grouping your data types by common behaviour.
def print_type_and_value_for_variable(i, indent=0):
print(indent * '\t', end='')
t = type(i)
if t in [str, int, float, bool, complex, bytes, bytearray, memoryview]:
# Print out type and value
print(f'{t.__name__}: {i}')
elif t in [list, tuple, range, set, frozenset, range]:
# Iterate using for j in i
print(f'{t.__name__}:')
for j in i:
print_type_and_value_for_variable(j, indent + 1)
elif t is dict:
# Iterate over items()
print(f'{t.__name__}:')
for key, value in i.items():
print(f" key '{print_type_and_value_for_variable(key, indent + 1)}' : value"
f" '{print_type_and_value_for_variable(value, indent + 1)}'")
elif i is None:
print(f'{t.__name__}: {i}')
else:
print(f"unknown variable type {type(i)}: {i}")
if __name__ == '__main__':
list_of_stuff = [1, 2, "words", ["inner", "list"],
{1: "one", 2: "two", "3": [3.1, 3.2, 3.3], 4: {1: "test", 2: "test2"}},
"words 2", 0.314]
for item in list_of_stuff:
print_type_and_value_for_variable(item)
Upvotes: 1