Novice [].append Help

W

waters

I seem to have hit a snag.

I am trying to add the list (l_local) as an item in the output list
(l_output). "l_local" is a modified copy of the format-list "l_format",
which will be updated by index position within the function. The problem
occurs in the following statement block:

def create_apid_list(l_format,l_values):
l_output = []
for t_curr_line in l_values: # ...for each list in the values list
l_local = l_format # ...assign blank format to local list
l_local[0] = t_curr_line[0] # ...modify with vendor number
l_local[1] = t_curr_line[1] # ...modify with invoice number
# print l_local # ... for testing
l_output.append(l_local) # ...add list as item to output list
return l_output

....the "l_output.append(l_local)" line is not returning the expected
result. It is correctly producing a list of lists, but they all contain
the the same values from the last t_curr_line[0] & t_curr_line[1]
records in the l_values list. The preceding print statement displays the
proper values containing data from all of the lists in l_values, so I'm
not sure what the problem is.

I would like to avoid using the extend module, as I hope to use each
list as a "line" when written to the output files.

The complete code is listed below, it uses the delimited.py module that
was posted on this newsgroups awhile back. Some lines may wrap.

Thanks for any help...


# thybidding.py
# Input - tab delimited input file.
# Output - pipe delimited output files formatted accordingly.

# Formats
l_apid_format = [
" ", # 00 apid_vendor integer
" ", # 01 apid_invoice char(12)
" ", # 02 apid_seq smallint
" ", # 03 apid_fund char(4)
" ", # 04 apid_desc char(30)
" ", # 05 apid_bud_dist char(1)
" ", # 06 apid_asset_sw char(1)
" ", # 07 apid_3rd_party integer
" ", # 08 apid_1099_cd char(1)
" ", # 09 apid_donate_cd char(2)
" ", # 10 apid_taxable_sc char(1)
" ", # 11 apid_org char(8)
" ", # 12 apid_obj char(6)
" ", # 13 apid_project char(5)
" ", # 14 apid_po char(8)
" ", # 15 apid_ap_cntl_org char(8)
" ", # 16 apid_ap_cntl_obj char(6)
" ", # 17 apid_ap_ctl_proj char(5)
" ", # 18 apid_over_bud char(1)
" ", # 19 apid_amt decimal(13,2)
" ", # 20 apid_txbl_amt_sc decimal(13,2)
" ", # 21 apid_po_fsc_yr smallint
" ", # 22 apid_po_liqd char(1)
" ", # 23 apid_key integer
" ", # 24 apid_fa_inv_qty decimal(7,1)
" ", # 25 apid_fa_inv_pct decimal(5,2)
" "] # 26 apid_asset char(15)
l_apih_format = [
" ", # 00 apih_vendor integer
" ", # 01 apih_invoice char(12)
" ", # 02 apih_type smallint
" ", # 03 apih_status char(1)
" ", # 04 apih_remit_no smallint
" ", # 05 apih_batch smallint
" ", # 06 apih_clerk char(8)
" ", # 07 apih_voucher char(8)
" ", # 08 apih_warrant char(8)
" ", # 09 apih_req char(8)
" ", # 10 apih_po char(8)
" ", # 11 apih_dept char(5)
" ", # 12 apih_ent char(1)
" ", # 13 apih_desc char(30)
" ", # 14 apih_cash_org char(8)
" ", # 15 apih_cash_obj char(6)
" ", # 16 apih_cash_proj char(5)
" ", # 17 apih_warr_org char(8)
" ", # 18 apih_warr_obj char(6)
" ", # 19 apih_warr_proj char(5)
" ", # 20 apih_sep_check char(1)
" ", # 21 apih_bud_dist char(1)
" ", # 22 apih_comments char(250)
" ", # 23 apih_je_year smallint
" ", # 24 apih_je_per smallint
" ", # 25 apih_inv_date date
" ", # 26 apih_disc_date date
" ", # 27 apih_due_date date
" ", # 28 apih_entry_date date
" ", # 29 apih_check_date date
" ", # 30 apih_check_no integer
" ", # 31 apih_inv_total decimal(13,2)
" ", # 32 apih_discbl_amt decimal(13,2)
" ", # 33 apih_disc_amt decimal(13,2)
" ", # 34 apih_inv_net decimal(13,2)
" ", # 35 apih_sales_tax1 decimal(8,2)
" ", # 36 apih_sales_tax2 decimal(8,2)
" ", # 37 apih_alpha_sort char(20)
" ", # 38 apih_wire_xfer char(8)
" ", # 39 apih_released char(1)
" ", # 40 apih_not_taxbl decimal(13,2)
" ", # 41 apih_county_cd char(3)
" ", # 42 apih_category char(1)
" ", # 43 apih_gl_effec_date date
" ", # 44 apih_cash_flow_cd char(8)
" ", # 45 apih_nxt_approv char(8)
" ", # 46 apih_approv_lvl smallint
" ", # 47 apih_wf_aprv_err char(1)
" ", # 48 apih_wo integer
" "] # 49 apih_contract char(10)

# Variables
s_input_file = "/input/input.dat"
s_apid_output_path = "/output/apid_output.dat"
s_apih_output_path = "/output/apih_output.dat"

# Output Files
f_apid_output = open(s_apid_output_path,'w')
f_apih_output = open(s_apih_output_path,'w')

# Modules
import delimited # ...for reading tab or space delimited files
import string # ...for list to string conversion

# Functions
def retrieve_values():
l_output = []
for t_curr_line in
delimited.split_delimited(open(s_input_file,'r').read()):
l_output.append(t_curr_line)
return l_output

def create_apid_list(l_format,l_values):
l_output = []
for t_curr_line in l_values: # ...for each line in the values list
l_local = l_format # ...assign format to list
l_local[0] = t_curr_line[0] # ...assign vendor number
l_local[1] = t_curr_line[1] # ...assign invoice number
# ...many more of these will follow. snipped for brevity
# print l_local # <-- for testing
l_output.append(l_local)
return l_output


def create_apih_list(l_format,l_values):
# currently unimplemented


def delimiterize(l_input):
# currently unimplemented


def writefile(l_input_data,f_output_file):
for l_line in l_input_data:
f_output_file.write(l_line)


# Calls
l_values = retrieve_values()
l_apid = create_apid_list(l_apid_format,l_values)

# Unused
# l_apih = create_apih_list(l_apih_format,l_values)
# l_apid_delimited = delimiterize(l_apid)
# l_apih_delimited = delimiterize(l_apih)
# writefile(l_apid_delimited,s_apid_output)
# writefile(l_apih_delimited,s_apih_output)
 
J

Jeff Epler

First a gripe about your code: the l_ stuff is painful to read.

Anyway, the line
l_local = l_format
merely makes l_local a reference to the same thing as l_format (l_local
is l_format). The next two lines change some of the elements in that
list, and then l_output gets another reference to the same list added to
it. It's no surprise, then, that all of l_output's items are equal when
the function is done: it's a list containing many references to the same
thing.

This may do what you want if you change that line to
l_local = l_format[:]
seq[:] is a slice including all the elements of seq, and is a very
common shorthand for making a shallow copy. You could also write
l_local = t_curr_line[:2] + l_format[2:]
to assemble l_local from slices of other lists.

Here's how I'd be tempted to write your function:

def create_apid_list(format, values):
return [ v[:2] + format[2:] for v in values ]

or, if the context allows for the use of an iterator and you're using
Python 2.3:

def create_apid_list(format, values):
for v in values:
yield v[:2] + format[2:]

Jeff
 
J

John Roth

waters said:
I seem to have hit a snag.

I am trying to add the list (l_local) as an item in the output list
(l_output). "l_local" is a modified copy of the format-list "l_format",
which will be updated by index position within the function. The problem
occurs in the following statement block:

def create_apid_list(l_format,l_values):
l_output = []
for t_curr_line in l_values: # ...for each list in the values list
l_local = l_format # ...assign blank format to local list
l_local[0] = t_curr_line[0] # ...modify with vendor number
l_local[1] = t_curr_line[1] # ...modify with invoice number
# print l_local # ... for testing
l_output.append(l_local) # ...add list as item to output list
return l_output

...the "l_output.append(l_local)" line is not returning the expected
result. It is correctly producing a list of lists, but they all contain
the the same values from the last t_curr_line[0] & t_curr_line[1]
records in the l_values list. The preceding print statement displays the
proper values containing data from all of the lists in l_values, so I'm
not sure what the problem is.

You've fallen into one of the little traps. There's only *one*
copy of the l_format list, and it's being bound to l_local each
time through the loop. Assignment is *not* creating a copy of
the l_format list; it's reusing it, so each slot in the l_output list
is pointing to the *same* list, which of course contains the last
value you put into it.

If you change the 4th line to:

l_local = list(l_format)

it will work because the list type will produce a copy.

John Roth
 
W

waters

John said:
You've fallen into one of the little traps. There's only *one*
copy of the l_format list, and it's being bound to l_local each
time through the loop. Assignment is *not* creating a copy of
the l_format list; it's reusing it, so each slot in the l_output list
is pointing to the *same* list, which of course contains the last
value you put into it.

If you change the 4th line to:

l_local = list(l_format)

it will work because the list type will produce a copy.

John Roth

Thanks for this, and all subsequent replies. Will keep an eye out for
these (coder-induced) assignment issues.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top