Index Enumeration doesn't seem to be operating properly. Where am I messing up?

Question:

I’m trying to figure out how to enumerate an index properly into specified cells on an Excel spreadsheet using Python. Following a tutorial video, I thought I had it figured out, but it doesn’t seem to be pulling each index value and parsing it to each individual cell as intended. Instead, it’s taking only the first entry and applying it to all specified cells and ignoring the second and third entry. Can someone help me understand where I’m messing up on this? Thank you kindly.

Code:

from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter

wb = load_workbook('PythonNetwork.xlsx')  
ws = wb['Systems']  
print(ws)  

# Shows each designated cell as well as its cell value.
for row in ws['A2':'A4']:
    for cell in row:  
        print(cell, cell.value) 

new_data = ["192.168.1.4", "192.168.1.5", "192.168.1.6"]

# Enters new data from created index.
for row in ws['A2':'A4']:
    for index, cell in enumerate(row):
        cell.value = new_data[index]

# Shows each designated cell value for comparison to previously printed information.
for row in ws['A2':'A4']:
    for cell in row: 
        print(cell.value) 

Output:

<Worksheet "Systems">
<Cell 'Systems'.A2> 192.168.1.1
<Cell 'Systems'.A3> 192.168.1.2
<Cell 'Systems'.A4> 192.168.1.3
192.168.1.4
192.168.1.4
192.168.1.4

I tried changing the values in the index from having quotes to simple integers without quotes to see if it made any difference. It does not. For example I replaced each IP address in the index with 10, 20, etc as shown below:

new_data = [10, 20, 30]

The output was the same result as each cell reported back as 10 10 10 instead of 10 20 30.

Asked By: stijeger

||

Answers:

Unfortunately, this manner of accessing a range of cells is always a bit clumsy. If you look at what accessing the range returns:

>>> ws['A2':'A4']
((<Cell 'Systems'.A2>,), (<Cell 'Systems'.A3>,), (<Cell 'Systems'.A4>,))

it’s a tuple of tuples, where each inner tuple is a single cell. So, in your for loop, what you’re calling a row is a tuple of a single cell. It’s not a row exactly, but your code to print those cells works anyway.

When you try to change the values, though, the enumeration index is always 0, since each tuple has a single cell, so you’re always assigning the value of new_data[0].

Instead, you can do something like this:

for index, cell in enumerate(ws['A2':'A4']):
    cell[0].value = new_data[index]

Each cell is actually a tuple of a cell, so you have to reference the 0th element.

Answered By: sj95126