Adding rows to CSV sorted by ID in Python without reading whole file into memory
I have a CSV file where the first column is an ID like so:
5,a
4,b
2,c
1,d
The rows must always be sorted from the biggest to smallest ID. I have a list of rows that I want to add, without reading the whole original CSV in memory, so I can't just append the rows and sort after. Here is the code I came up with:
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
for new_row in rows_to_add:
for source_row in reader:
if new_row[0] >= int(source_row[0]):
writer.writerow(new_row)
writer.writerow(source_row)
break
writer.writerow(source_row)
else:
# If source reader already reached end of file
writer.writerow(new_row)
for remaining_line in in_file:
out_file.write(remaining_line)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
Result:
7,NEW1
5,a
6,NEW2
4,b
3,NEW3
2,c
1,d
-2,NEW4
This doesn't work correctly if there are two consecutive IDs, 6,NEW2
should be just after 7,NEW1
and I can't figure out the right way to do it.
python csv
add a comment |
I have a CSV file where the first column is an ID like so:
5,a
4,b
2,c
1,d
The rows must always be sorted from the biggest to smallest ID. I have a list of rows that I want to add, without reading the whole original CSV in memory, so I can't just append the rows and sort after. Here is the code I came up with:
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
for new_row in rows_to_add:
for source_row in reader:
if new_row[0] >= int(source_row[0]):
writer.writerow(new_row)
writer.writerow(source_row)
break
writer.writerow(source_row)
else:
# If source reader already reached end of file
writer.writerow(new_row)
for remaining_line in in_file:
out_file.write(remaining_line)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
Result:
7,NEW1
5,a
6,NEW2
4,b
3,NEW3
2,c
1,d
-2,NEW4
This doesn't work correctly if there are two consecutive IDs, 6,NEW2
should be just after 7,NEW1
and I can't figure out the right way to do it.
python csv
add a comment |
I have a CSV file where the first column is an ID like so:
5,a
4,b
2,c
1,d
The rows must always be sorted from the biggest to smallest ID. I have a list of rows that I want to add, without reading the whole original CSV in memory, so I can't just append the rows and sort after. Here is the code I came up with:
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
for new_row in rows_to_add:
for source_row in reader:
if new_row[0] >= int(source_row[0]):
writer.writerow(new_row)
writer.writerow(source_row)
break
writer.writerow(source_row)
else:
# If source reader already reached end of file
writer.writerow(new_row)
for remaining_line in in_file:
out_file.write(remaining_line)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
Result:
7,NEW1
5,a
6,NEW2
4,b
3,NEW3
2,c
1,d
-2,NEW4
This doesn't work correctly if there are two consecutive IDs, 6,NEW2
should be just after 7,NEW1
and I can't figure out the right way to do it.
python csv
I have a CSV file where the first column is an ID like so:
5,a
4,b
2,c
1,d
The rows must always be sorted from the biggest to smallest ID. I have a list of rows that I want to add, without reading the whole original CSV in memory, so I can't just append the rows and sort after. Here is the code I came up with:
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
for new_row in rows_to_add:
for source_row in reader:
if new_row[0] >= int(source_row[0]):
writer.writerow(new_row)
writer.writerow(source_row)
break
writer.writerow(source_row)
else:
# If source reader already reached end of file
writer.writerow(new_row)
for remaining_line in in_file:
out_file.write(remaining_line)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
Result:
7,NEW1
5,a
6,NEW2
4,b
3,NEW3
2,c
1,d
-2,NEW4
This doesn't work correctly if there are two consecutive IDs, 6,NEW2
should be just after 7,NEW1
and I can't figure out the right way to do it.
python csv
python csv
edited Nov 15 '18 at 1:22
sena
asked Nov 15 '18 at 0:36
senasena
134
134
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You have to use a running pointer for at least one of the lists. In this case, as you can't read the entire CSV, the running pointer can be used for the other list
Following code should work
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
idx = 0
# For each line in file
for source_row in reader:
# Print all rows from rows_to_add that are larger
while rows_to_add[idx][0] > int(source_row[0]):
writer.writerow(rows_to_add[idx])
idx += 1
# Before printing current line from file
writer.writerow(source_row)
# Print remaining rows in rows_to_add
for row in rows_to_add[idx:]:
writer.writerow(row)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
sample output for your in.csv
7,NEW1
6,NEW2
6,NEW2
5,a
4,b
3,NEW3
2,c
1,d
-2,NEW4
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310840%2fadding-rows-to-csv-sorted-by-id-in-python-without-reading-whole-file-into-memory%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You have to use a running pointer for at least one of the lists. In this case, as you can't read the entire CSV, the running pointer can be used for the other list
Following code should work
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
idx = 0
# For each line in file
for source_row in reader:
# Print all rows from rows_to_add that are larger
while rows_to_add[idx][0] > int(source_row[0]):
writer.writerow(rows_to_add[idx])
idx += 1
# Before printing current line from file
writer.writerow(source_row)
# Print remaining rows in rows_to_add
for row in rows_to_add[idx:]:
writer.writerow(row)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
sample output for your in.csv
7,NEW1
6,NEW2
6,NEW2
5,a
4,b
3,NEW3
2,c
1,d
-2,NEW4
add a comment |
You have to use a running pointer for at least one of the lists. In this case, as you can't read the entire CSV, the running pointer can be used for the other list
Following code should work
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
idx = 0
# For each line in file
for source_row in reader:
# Print all rows from rows_to_add that are larger
while rows_to_add[idx][0] > int(source_row[0]):
writer.writerow(rows_to_add[idx])
idx += 1
# Before printing current line from file
writer.writerow(source_row)
# Print remaining rows in rows_to_add
for row in rows_to_add[idx:]:
writer.writerow(row)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
sample output for your in.csv
7,NEW1
6,NEW2
6,NEW2
5,a
4,b
3,NEW3
2,c
1,d
-2,NEW4
add a comment |
You have to use a running pointer for at least one of the lists. In this case, as you can't read the entire CSV, the running pointer can be used for the other list
Following code should work
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
idx = 0
# For each line in file
for source_row in reader:
# Print all rows from rows_to_add that are larger
while rows_to_add[idx][0] > int(source_row[0]):
writer.writerow(rows_to_add[idx])
idx += 1
# Before printing current line from file
writer.writerow(source_row)
# Print remaining rows in rows_to_add
for row in rows_to_add[idx:]:
writer.writerow(row)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
sample output for your in.csv
7,NEW1
6,NEW2
6,NEW2
5,a
4,b
3,NEW3
2,c
1,d
-2,NEW4
You have to use a running pointer for at least one of the lists. In this case, as you can't read the entire CSV, the running pointer can be used for the other list
Following code should work
import csv
def main():
rows_to_add = [[7, "NEW1"], [6, "NEW2"], [6, "NEW2"], [3, "NEW3"], [-2, "NEW4"]]
with open("in.csv", "r") as in_file, open("out.csv", "w") as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
idx = 0
# For each line in file
for source_row in reader:
# Print all rows from rows_to_add that are larger
while rows_to_add[idx][0] > int(source_row[0]):
writer.writerow(rows_to_add[idx])
idx += 1
# Before printing current line from file
writer.writerow(source_row)
# Print remaining rows in rows_to_add
for row in rows_to_add[idx:]:
writer.writerow(row)
with open("out.csv", "r") as out_file:
print(out_file.read())
if __name__ == "__main__":
main()
sample output for your in.csv
7,NEW1
6,NEW2
6,NEW2
5,a
4,b
3,NEW3
2,c
1,d
-2,NEW4
answered Nov 15 '18 at 1:58
KrishnaKrishna
6021515
6021515
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310840%2fadding-rows-to-csv-sorted-by-id-in-python-without-reading-whole-file-into-memory%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown