11
\$\begingroup\$

I was wondering if there is a smarter way of doing the following code. Basically what is does is that it opens a data file with a lot of rows and columns. The columns are then sorted so each column is a vector with all the data inside.

"3.2.2 - Declare variables"
lineData = list()
for line in File:
 splittedLine = line.split() # split
 lineData.append(splittedLine) #collect 

And here the fun begins

"3.2.3 - define desired variables from file"
col1 = "ElemNo"
col2 = "Node1"
col3 = "Node2"
col4 = "Length"
col5 = "Area"
col6 = "Inertia"
col7 = "Fnode1"
col8 = "Fnode2"
col9 = "SigmaMin"
col10 = "SigmaMax"
"3.2.3 - make each variable as a list/vector"
var ={col1:[], col2:[], col3:[], col4:[], col5:[], col6:[], col7:[], col8:[]
 ,col9:[],col10:[]} 
"3.2.3 - take the values from each row in lineData and collect them into the correct variable"
for row in lineData:
 var[col1] .append(float(row[0]) ) #[-] ElemNo
 var[col2] .append(float(row[1]) ) #[-] Node1
 var[col3] .append(float(row[2]) ) #[-] Node2
 var[col4] .append(float(row[3]) ) #[mm] Length
 var[col5] .append(float(row[4]) ) #[mm^2] Area
 var[col6] .append(float(row[5])*10**6) #[mm^4] Inertia 
 var[col7] .append(float(row[6]) ) #[N] Fnode1
 var[col8] .append(float(row[7]) ) #[N] Fnode2
 var[col9] .append(float(row[8]) ) #[MPa] SigmaMin
 var[col10].append(float(row[9]) ) #[MPa] SigmaMax

As you see this is a rather annoying way of making each row into a variable. Any suggestions?

rolfl
98.1k17 gold badges219 silver badges419 bronze badges
asked Feb 25, 2014 at 9:44
\$\endgroup\$

3 Answers 3

8
\$\begingroup\$

First of all don't create variables for those keys, store them in a list.

keys = ["ElemNo", "Node1", "Node2", "Length", "Area", "Inertia",
 "Fnode1", "Fnode2", "SigmaMin", "SigmaMax"]

You can use collections.defaultdict here, so no need to initialize the dictionary with those keys and empty list.

from collections import defaultdict
var = defaultdict(list)

Now, instead of storing the data in a list, you can populate the dictionary during iteration over File itself.

for line in File:
 for i, (k, v) in enumerate(zip(keys, line.split())):
 if i == 5:
 var[k].append(float(v)*10**6)
 else:
 var[k].append(float(v)) 
answered Feb 25, 2014 at 9:44
\$\endgroup\$
2
  • \$\begingroup\$ Maybe i == 5 -> k == 'Inertia'? \$\endgroup\$ Commented Feb 25, 2014 at 19:21
  • \$\begingroup\$ @tokland But you've already included that in your answer. If you don't mind then I can suggest that in my answer as well. \$\endgroup\$ Commented Feb 25, 2014 at 19:25
6
\$\begingroup\$

In functional approach, without refering to meaningless numeric indexes but column names, and creating a dictionary with "ElemNo" as keys instead of a dict of lists, I'd write:

columns = [
 "ElemNo", "Node1", "Node2", "Length", "Area", "Inertia",
 "Fnode1", "Fnode2", "SigmaMin", "SigmaMax",
]
def process_line(line):
 def get_value(column, value):
 if column == "Inertia":
 return float(value) * (10**6)
 else:
 return float(value)
 elem = {col: get_value(col, value) for (col, value) in zip(columns, line.split())}
 return (elem["ElemNo"], elem)
data = dict(process_line(line) for line in fd)
answered Feb 25, 2014 at 12:26
\$\endgroup\$
2
  • \$\begingroup\$ How would this be better from the first suggestion? \$\endgroup\$ Commented Feb 25, 2014 at 13:34
  • 2
    \$\begingroup\$ @MikkelGrauballe: 1) don't use numeric indexes, 2) functional approach, 3) use elemno as key so finding elements is easier. Maybe not better, but it's a different approach. \$\endgroup\$ Commented Feb 25, 2014 at 13:41
5
\$\begingroup\$

You can use zip to perform a transpose operation on a list of lists:

column_names = [
 "ElemNo", "Node1", "Node2", "Length", 
 "Area", "Inertia", "Fnode1", "Fnode2", 
 "SigmaMin", "SigmaMax"
]
columns = dict(zip(column_names, (map(float, col) for col in zip(*lineData))))
# transposes lineData ^^^
columns["Inertia"] = [x * 10 ** 6 for x in columns["Inertia"]]
answered Feb 25, 2014 at 16:39
\$\endgroup\$
1
  • 3
    \$\begingroup\$ I'm +1ing mainly for transforming Inertia separately from the transpose. It's a separate "rule", so I don't particularly like putting it inside the main transpose loop, however that loop was done. \$\endgroup\$ Commented Feb 25, 2014 at 19:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.