Python Forum
What type of *data* is the name of a list/tuple/dict, etc?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What type of *data* is the name of a list/tuple/dict, etc?
#1
In this excerpt of something I'm playing with, I create a variable from the user input. The user inpout is then added to a string. The resultant string is then used to refer to a list.

But, when I try to print the contents of the list, the output is just the list's name, not the contents of the list itself. The script is:

thermistor_list = ["0.1K1A", "0.3K1A", "1K2A", "1K7A", "2K3A", "2.2K3A", "3K3A", "5K3A", "10K3A", "10K4A", "30K5A", "30K6A", "50K6A", "100K6A", "1M9A"]
device_list = ["device0", "device1", "device2", "device3 ", "device4", "device5", "device6", "device7", "device8", "device9", "device10", "device11 ", "device12", "device13", "device14"]
device0 =  [1.942952*10**-3, 2.989769*10**-4, 3.504383*10**-7]  # 0.1K1A
device1 =  [1.627660*10**-3, 2.933316*10**-4, 2.870016*10**-7]  # 0.3K1A 
device2 =  [1.373168*10**-3, 2.772261*10**-4, 1.997412*10**-7]  # 1K2A
device3 =  [1.446059*10**-3, 2.683626*10**-4, 1.643561*10**-7]  # 1K7A
device4 =  [1.498872*10**-3, 2.379047*10**-4, 1.066953*10**-7]  # 2K3A
device5 =  [1.471388*10**-3, 2.376138*10**-4, 1.051058*10**-7]  # 2.2K3A
device6 =  [1.405027*10**-3, 2.369386*10**-4, 1.012660*10**-7]  # 3K3A
device7 =  [1.287450*10**-3, 2.357394*10**-4, 9.505200*10**-8]  # 5K3A
device8 =  [1.129241*10**-3, 2.341077*10**-4, 8.775468*10**-8]  # 10K3A
device9 =  [1.028444*10**-3, 2.392435*10**-4, 1.562216*10**-7]  # 10K4A
device10 = [9.331754*10**-4, 2.213978*10**-4, 1.263817*10**-7]  # 30K5A
device11 = [1.068981*10**-3, 2.120700*10**-4, 9.019537*10**-8]  # 30K6A
device12 = [9.657154*10**-4, 2.106840*10**-4, 8.585481*10**-8]  # 50K6A
device13 = [8.271111*10**-4, 2.088020*10**-4, 8.059200*10**-8]  # 100K6A
device14 = [7.402387*10**-4, 1.760865*10**-4, 6.865999*10**-8]  # 1M9A
    # NOTE: 2.2K3A is OK-ish - Gives 25.53 °C @ 2200 Ω

# SELECT THERMISTOR TYPE TO BE MEASURED AND EXTRACT CONSTANTS

print("Devices available:")
for index, value in enumerate(thermistor_list): 
    print(index, value, sep=": ")

device_number = int(input("Select the device to be measured = 0 to 14: "))
x = int(device_number)
selected_thermistor = (thermistor_list[x])
selected_device = (device_list[x])
print("Selected thermistor is", selected_thermistor)
print(selected_device) # Prints contents of user selected list
print(device14) # Prints content of list by naming it directly
The output looks like this:

Devices available:
0: 0.1K1A
1: 0.3K1A
2: 1K2A
3: 1K7A
4: 2K3A
5: 2.2K3A
6: 3K3A
7: 5K3A
8: 10K3A
9: 10K4A
10: 30K5A
11: 30K6A
12: 50K6A
13: 100K6A
14: 1M9A
Select the device to be measured = 0 to 14:
14
Selected thermistor is 1M9A
device14
[0.0007402387000000001, 0.0001760865, 6.865999000000001e-08]


You can see that when I input "14", the output correctly tells me the selected device is 1M9A, but then instead of printing the contents of list device14, it just prints "device14", its name.
The last line is just to show what should be printed.

I have tried:
selected_device = str(device_list[x])
but the output is the same.
I also tried:
selected_device = list(device_list[x])
the output was:
['d', 'e', 'v', 'i', 'c', 'e', '1', '4']

So, what is the difference between the value for selected_device and the same value (in this case device14) and the actual list name?
Reply
#2
Instead of defining a variable name for each device, define a list directly
device_list = [
    [1.942952*10**-3, 2.989769*10**-4, 3.504383*10**-7],  # 0.1K1A
    [1.627660*10**-3, 2.933316*10**-4, 2.870016*10**-7],  # 0.3K1A 
    [1.373168*10**-3, 2.772261*10**-4, 1.997412*10**-7],  # 1K2A
    [1.446059*10**-3, 2.683626*10**-4, 1.643561*10**-7],  # 1K7A
    [1.498872*10**-3, 2.379047*10**-4, 1.066953*10**-7],  # 2K3A
    [1.471388*10**-3, 2.376138*10**-4, 1.051058*10**-7],  # 2.2K3A
    [1.405027*10**-3, 2.369386*10**-4, 1.012660*10**-7],  # 3K3A
    [1.287450*10**-3, 2.357394*10**-4, 9.505200*10**-8],  # 5K3A
    [1.129241*10**-3, 2.341077*10**-4, 8.775468*10**-8],  # 10K3A
    [1.028444*10**-3, 2.392435*10**-4, 1.562216*10**-7],  # 10K4A
    [9.331754*10**-4, 2.213978*10**-4, 1.263817*10**-7],  # 30K5A
    [1.068981*10**-3, 2.120700*10**-4, 9.019537*10**-8],  # 30K6A
    [9.657154*10**-4, 2.106840*10**-4, 8.585481*10**-8],  # 50K6A
    [8.271111*10**-4, 2.088020*10**-4, 8.059200*10**-8],  # 100K6A
    [7.402387*10**-4, 1.760865*10**-4, 6.865999*10**-8],  # 1M9A
]
print(device_list[14])
Output:
[0.0007402387000000001, 0.0001760865, 6.865999000000001e-08]
Also instead of 8.059200*10**-8, it is better to use Python's syntax and write 8.059200e-8. In this case, the two numbers differ by 1 bit.

About your question in the title of this thread: there is no data type that would be a 'variable'. A variable in Python is only a string, a key in a dictionary. There is nothing like a 'pointer to pointer' as you would find in other languages such as C.
bowlofred and alloydog like this post
Reply
#3
device_list is just a list of character strings. So when you print one element of it, it's just the string that is printed.

device_list = ["device0", "device1", "device2", "device3 ", "device4", "device5", "device6", "device7", "device8", "device9", "device10", "device11 ", "device12", "device13", "device14"]
...
selected_device = (device_list[x])  # this will be a string like "device14"
print(selected_device) # And here it is printed out.
alloydog likes this post
Reply
#4
when you do selected_device = (device_list[x]), selected_device is just a string, it's not the list as you think. Now, there is a way to do what you want, but it is plainly WRONG (you don't create names dynamically but it's the same problem). You should use a proper structure. in this case - a dict looks OK. The key would be the thermistor name, e.g. "0.1K1A" and the value will be the list - [1.942952*10**-3, 2.989769*10**-4, 3.504383*10**-7]

You can go further and instead of list use namedtuple (these are fixed values, fixed-len lists, right?). This is short of creating custom class, but makes it much better, no magic numbers (e.g. I don't know what 1.942952*10**-3 represents).


In the example I stick to list of devices but implement devices as namedtuple


from collections import namedtuple

Device = namedtuple('Device', 'part_no coef_a coef_b coef_c')

devices = [
    Device('0.1K1A', 1.942952*10**-3, 2.989769*10**-4, 3.504383*10**-7),  # 0.1K1A
    Device('0.3K1A', 1.627660*10**-3, 2.933316*10**-4, 2.870016*10**-7),  # 0.3K1A 
    Device('1K2A', 1.373168*10**-3, 2.772261*10**-4, 1.997412*10**-7),  # 1K2A
    Device('1K7A', 1.446059*10**-3, 2.683626*10**-4, 1.643561*10**-7),  # 1K7A
    Device('2K3A', 1.498872*10**-3, 2.379047*10**-4, 1.066953*10**-7),  # 2K3A
    Device('2.K3A', 1.471388*10**-3, 2.376138*10**-4, 1.051058*10**-7),  # 2.2K3A
    Device('3K3A', 1.405027*10**-3, 2.369386*10**-4, 1.012660*10**-7),  # 3K3A
    Device('5K3A', 1.287450*10**-3, 2.357394*10**-4, 9.505200*10**-8),  # 5K3A
    Device('10K3A', 1.129241*10**-3, 2.341077*10**-4, 8.775468*10**-8),  # 10K3A
    Device('10K4A', 1.028444*10**-3, 2.392435*10**-4, 1.562216*10**-7),  # 10K4A
    Device('30K5A', 9.331754*10**-4, 2.213978*10**-4, 1.263817*10**-7),  # 30K5A
    Device('30K6A', 1.068981*10**-3, 2.120700*10**-4, 9.019537*10**-8),  # 30K6A
    Device('50K6A', 9.657154*10**-4, 2.106840*10**-4, 8.585481*10**-8),  # 50K6A
    Device('100K6A', 8.271111*10**-4, 2.088020*10**-4, 8.059200*10**-8),  # 100K6A
    Device('1M9A', 7.402387*10**-4, 1.760865*10**-4, 6.865999*10**-8)]  # 1M9A


for idx, device in enumerate(devices, start=1):
    print(f'{idx: >2d}.{device.part_no}')
user_choice = int(input(f'Select device (1-{len(devices)}): ')) - 1

device = devices[user_choice]
print(device)
print(device.part_no)
print(device.coef_b)
Output:
1.0.1K1A 2.0.3K1A 3.1K2A 4.1K7A 5.2K3A 6.2.K3A 7.3K3A 8.5K3A 9.10K3A 10.10K4A 11.30K5A 12.30K6A 13.50K6A 14.100K6A 15.1M9A Select device (1-15): 13 Device(part_no='50K6A', coef_a=0.0009657154, coef_b=0.00021068400000000002, coef_c=8.585481e-08) 50K6A 0.00021068400000000002
alloydog likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
For something like this I would use a dictionary or database depending on if the device list is fixed or fluid. This is an example of using a dictionary.
devices = {
    "0.1K1A":[1.942952*10**-3, 2.989769*10**-4, 3.504383*10**-7],
    "0.3K1A":[1.627660*10**-3, 2.933316*10**-4, 2.870016*10**-7],
    "1K2A"  :[1.373168*10**-3, 2.772261*10**-4, 1.997412*10**-7],
    "1K7A"  :[1.446059*10**-3, 2.683626*10**-4, 1.643561*10**-7],
    "2K3A"  :[1.498872*10**-3, 2.379047*10**-4, 1.066953*10**-7],
    "2.2K3A":[1.471388*10**-3, 2.376138*10**-4, 1.051058*10**-7],
    "3K3A"  :[1.405027*10**-3, 2.369386*10**-4, 1.012660*10**-7],
    "5K3A"  :[1.287450*10**-3, 2.357394*10**-4, 9.505200*10**-8],
    "10K3A" :[1.129241*10**-3, 2.341077*10**-4, 8.775468*10**-8],
    "10K4A" :[1.028444*10**-3, 2.392435*10**-4, 1.562216*10**-7],
    "30K5A" :[9.331754*10**-4, 2.213978*10**-4, 1.263817*10**-7],
    "30K6A" :[1.068981*10**-3, 2.120700*10**-4, 9.019537*10**-8],
    "50K6A" :[9.657154*10**-4, 2.106840*10**-4, 8.585481*10**-8],
    "100K6A":[8.271111*10**-4, 2.088020*10**-4, 8.059200*10**-8],
    "1M9A"  :[7.402387*10**-4, 1.760865*10**-4, 6.865999*10**-8]
}

def select_device():
    while True:
        for index, name in enumerate(devices):
            print(f'{index+1:2d}: {name}')
        name = input('Enter device name or number : ').upper()

        if not name in devices:
            try:
                name = list(devices.keys())[int(name)]
            except:
                pass

        dev = devices.get(name, None)
        if dev is not None:
            return name, dev

print(select_device())
alloydog likes this post
Reply
#6
Thanks for the detailed solutions! Thumbs Up

I will give each of them a try and see how they work and for tidying up the exponentials. Also, I wasn't sure how to format exponentials and *10**N worked Big Grin

buran - Yes, from various webby-searches looking into the problem, I got the idea that is was not a good idea, but I had tried various things, using dict, tuples and so on, but hadn't got anywhere. I did not know how to deal with it using the solutions (whiles, ifs and what-nots) you guys presented.

I now have several methods to play with, so I'll crawl back into my pit for a few days and let you know how it worked out then.

Cheers!
Reply
#7
(Jan-13-2021, 08:18 PM)buran Wrote:
for idx, device in enumerate(devices, start=1):
    print(f'{idx: >2d}.{device.part_no}')
user_choice = int(input(f'Select device (1-{len(devices)}): ')) - 1

I'm going through the various replies and solutions bit by bit (I want understand what each bit does, rather than just copy/paste and say "yee ha!" it works...)

From the namedtuple solution from @buran - I pretty much get what each bit does, except >2d. I even removed : >2d from the script, ran it and it worked pretty much the same.

What does the : >2d bit do?
Reply
#8
This is a format specification. Format spec mini-language

> - Right aligned
2 - Min field width
d - Numeric decimal
alloydog likes this post
Reply
#9
(Jan-28-2021, 05:01 PM)alloydog Wrote: What does the : >2d bit do?
As pointed by @bowlofred, it's a string formatting.

(Jan-28-2021, 05:01 PM)alloydog Wrote: it worked pretty much the same

The only purpose in this case is pure presentation - the menu items are aligned so that dot is in one column (i.e. numbering is right-aligned)
(Jan-28-2021, 05:01 PM)alloydog Wrote: I want understand what each bit does, rather than just copy/paste and say "yee ha!" it works...
that's the correct attitude and the reason why forum exists in the first place :-)
alloydog likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#10
Thanks!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Help with to check an Input list data with a data read from an external source sacharyya 3 318 Mar-09-2024, 12:33 PM
Last Post: Pedroski55
  using > < for tuple , list,... akbarza 3 401 Feb-05-2024, 01:18 PM
Last Post: deanhystad
Question mypy unable to analyse types of tuple elements in a list comprehension tomciodev 1 427 Oct-17-2023, 09:46 AM
Last Post: tomciodev
  Change font in a list or tuple apffal 4 2,635 Jun-16-2023, 02:55 AM
Last Post: schriftartenio
  search in dict inside tuple steg 1 647 Mar-29-2023, 01:15 PM
Last Post: rob101
  search a list or tuple for a specific type ot class Skaperen 8 1,854 Jul-22-2022, 10:29 PM
Last Post: Skaperen
  TypeError: unsupported operand type(s) for +: 'dict' and 'int' nick12341234 1 9,207 Jul-15-2022, 04:04 AM
Last Post: ndc85430
  Membership test for an element in a list that is a dict value for a particular key? Mark17 2 1,161 Jul-01-2022, 10:52 PM
Last Post: Pedroski55
  Are list/dict comprehensions interpreted really sequentially? anata2047 3 1,413 May-31-2022, 08:43 PM
Last Post: Gribouillis
  TypeError: unsupported opperand type(s) for %: 'int' and 'list' cool_person 7 2,096 May-07-2022, 08:40 AM
Last Post: ibreeden

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020