1

I am reading from a file.txt which has discrete data of Node id's and their respective x-axis and y-axis positions in each line:

Node_1 20.00 35.50

Node_2 77.00 21.40

Node_3 43.50 98.30


Now, I want to read this data to form lists in python script.py:

Node_1 = [20.00 , 35.50]
 
Node_2 = [77.00 , 21.40]

Node_3 = [43.50 , 98.30]

nodes = [Nodes_1, Nodes_2, Nodes_3]

So ultimately I will be having a list for nodes like [ [20.00 , 35.50] , [77.00 , 21.40] ,[43.50 , 98.30] ].

I have tried it using this below python code:

inputlist = list()
fhand = open('file.txt','r')
for line in fhand:
    for word in line.split():
        inputlist.append(word)    
    //Value in inputlist[0]// = [inputlist[1],inputlist[2]]
    nodes.append(inputlist[0])
    del inputlist[:]

I am not finding the right way to fill the value inside inputlist[0] with the correct choice of python code.

Community
  • 1
  • 1

6 Answers6

1

I think it's better to use a dictionary, on the premise that the nodes are unique. If the nodes are not unique, we can use a list as values, but then you will have a list of lists in the values() method

You can do this by the following:

nodes_dict = dict()
with open('file.txt','r') as f:
    for line in f:
        node_name, xpos, ypos = line.split()
        #Nodes are not unique
        if node_name in nodes_dict.keys():
            nodes_dict[node_name].append([xpos, ypos])
        else:
            nodes_dict[node_name] = [[xpos, ypos]]
        #Nodes are unique
        nodes_dict[node_name] = [xpos, ypos]

node_names = nodes_dict.keys()
node_coordinates = nodes_dict.values()

EDIT

Better solution according to @bruno desthuilliers' comment:

from collections import defaultdict

nodes_dict = defaultdict()
with open('file.txt','r') as f:
    for line in f:
        node_name, xpos, ypos = line.split()
        #No check needed because defaultdict takes care of this
        #Otherwise check would be if node_name in nodes_dict
        nodes_dict[node_name].append([xpos, ypos])

node_names = nodes_dict.keys()
node_coordinates = nodes_dict.values()
SBylemans
  • 1,764
  • 13
  • 28
  • 1
    containment tests againts dicts are better done using `if key in dict` (which is O(1)) instead of `if key in dict.keys()` which is O(n) (and in py2.x adds the overhead of creating the `keys` list). Also for such a case you want to use a `collections.defaultdict` instead. – bruno desthuilliers Dec 13 '18 at 13:01
0

this should do the job:

nodes = list()
fhand = open('file.txt','r')
for line in fhand:
    nodes.append(line.split()[1:])
ddor254
  • 1,570
  • 1
  • 12
  • 28
0

You are close. The main problems are:

  • You don't ignore the first column containing Node_1, Node_2, etc. Index via [1:] for this.
  • You need to convert strings to float.
  • You need to include all values for each row, not just the first, so no need to index [0].

Here's a demonstration:

from io import StringIO

file = StringIO("""Node_1 20.00 35.50
Node_2 77.00 21.40
Node_3 43.50 98.30""")

fhand = file  # use open('file.txt','r') instead of file

nodes = []
for line in fhand:
    inputlist = []
    for value in line.split()[1:]:
        inputlist.append(float(value))    
    nodes.append(inputlist)

print(nodes)

[[20.0, 35.5], [77.0, 21.4], [43.5, 98.3]]
jpp
  • 159,742
  • 34
  • 281
  • 339
0

I also suggest to use a dict, this is another option to build it, when no duplicated names exist.

text_file = open("file.txt", "r")
lines = text_file.read().splitlines()
s_lines = [ line.split() for line in lines ]

nodes = { line[0]: [float(x) for x in line[1:]] for line in s_lines }

print (nodes)
#=> {'Node_3': [43.5, 98.3], 'Node_2': [77.0, 21.4], 'Node_1': [20.0, 35.5]}

Check this topic: How do I create a variable number of variables?

iGian
  • 11,023
  • 3
  • 21
  • 36
-1

If I understand your question correctly, this should give you the expected result:

nodes = []
with open('file.txt','r') as f:
    for lineno, line in enumerate(f, 1):
        line = line.strip()
        if not line:
            continue
        try:
            node_name, xpos, ypos = line.split()
            nodes.append([float(xpos), float(ypos)])
        except Exception as e:
            print("line #{} seems broken (got {})".format(lineno, e))
            continue  

print(nodes)

EDIT: you say

I want to create the following lists first: Node_1 = [20.00 , 35.50] Node_2 = [77.00 , 21.40] Node_3 = [43.50 , 98.30]

The point is: since you don't know how many "nodes" you will have in your file, you can't know how many 'node_xxx' variable you will need - and you ALREADY have those values as nodes[xxx] anyway. Now if you want to keep the node names too, just use a dict instead of a list:

nodes = {}
with open('file.txt','r') as f:
    for lineno, line in enumerate(f, 1):
        line = line.strip()
        if not line:
            continue
        try:
            node_name, xpos, ypos = line.split()
            nodes[node_name] = [float(xpos), float(ypos)]
        except Exception as e:
            print("line #{} seems broken (got {})".format(lineno, e))
            continue  

print(nodes)
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Sir, I want to create the following lists first: Node_1 = [20.00 , 35.50] Node_2 = [77.00 , 21.40] Node_3 = [43.50 , 98.30] And later on, add the above lists to nodes list: nodes = [Node_1, Node_2, Node_3] Is there any solution to follow the sequence as I mentioned? – Dilip Kumar Dec 13 '18 at 12:11
  • Actually, no, you very probably dont. Read this for more on the topic of "variables variables": https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables – bruno desthuilliers Dec 13 '18 at 12:14
-1

Whenever you want to

  • enumerate variable names
  • create variables

you are thinking in the wrong direction. Instead of enumerating, use a list to capture your values. If you want to name things in a useful way (node1, node2, node3 are not useful in the sense that they are still just nodes that can as well be identified by an index) you want to use a dictionary. E.g.

cities = {}
cities['hamburg'] = ...
cities['berlin'] = ...
cities['new-york'] = ...
deets
  • 6,285
  • 29
  • 28
  • @brunodesthuilliers How else would you interpret the "Read an input string and declare a variable with the same string name to assign a value to it in python" that an attempt at declaring a variable *name* from reading input? – deets Dec 13 '18 at 12:48
  • Also, the link you posted suggest pretty much the same as I do, regarding the use of dictionaries for accessing objects by dynamically determined names - so how is my interpretation of this question incorrect? – deets Dec 13 '18 at 12:51
  • What I meant was that the important part of this question was about creating the lists of coordinates from the input file - the part about "dynamic variables", while emphahised in the title, is really secondary when you read the question. FWIW I started by closing the question as a duplicate of the one I linked to before realising this... – bruno desthuilliers Dec 13 '18 at 12:58
  • I disagree with the your emphasis on what is the more important part. The OP himself clarified under *your* answer that he cares about the named sublists per node. And I also disagree with your assumption that because I put a different emphasis than you I haven't read the question. I have. Others have interpreted it in a similar vein. So I fail to see how I'm at a fault here. – deets Dec 13 '18 at 13:02
  • Well we'll have to agree to disagree then. – bruno desthuilliers Dec 13 '18 at 13:03
  • All for defending your interpretation it is then! – deets Dec 13 '18 at 13:06
  • As I already stated, if the only point in this question was about "variables variables", the question should not have been answered at all but closed as duplicate. – bruno desthuilliers Dec 13 '18 at 13:09
  • And you are telling me that there is no other question on stackoverflow than reads coordinate tuples from a file that makes your answer distinguished and worth giving instead of equally closing it as duplicate? – deets Dec 13 '18 at 13:20
  • If you can find a question that's an exact dup of this part, please feel free to vote to close this one as a dup, I couldn't care less. Are we done yet ? – bruno desthuilliers Dec 13 '18 at 13:24
  • I explicitely wrote in a comment above that I indeed "misjudged the question myself" at first. Anything else ? – bruno desthuilliers Dec 13 '18 at 13:32