Haras Brummi Haras Brummi - 2 months ago 7
Python Question

Python for loop over list with directories does not find every value

I have a list of directories. I try just to keep those, which are named by number and not have some string name, e.g. "lastStableBuild". The following code removes every non-digit named directory except from "lastUnsuccessfulBuild".

for dir in listdir:
print(dir, " ", end="")
if not dir.isdigit():
listdir.remove(dir)


While debugging I tried to print the whole list. There are several directories with "string names" listed, but not "lastUnsuccessfulBuild". Then I printed the whole list again, and now it was listed, and the other were removed. After executing the removal code again "lastUnsuccessfulBuild" was removed, too. I am really irritated.
This is the complete code:

listdir = os.listdir(rootdir)

for dir in listdir:
print(dir, " ", end="")
if not dir.isdigit():
listdir.remove(dir)
print("")
print("________________After first removal_____________________________")

for dir in listdir:
print(dir, " ", end="")

for dir in listdir:
if not dir.isdigit():
listdir.remove(dir)

print("")
print("________________After second removal_____________________________")
for dir in listdir:
print(dir, " ", end="")


Which produces the following output:

> python listdir.py
> 778 761 794 792 885 877 811 873 871 679
> 726 771 837 691 783 751 813 780 852 723 721 801 826
> 784 757 846 812 782 724 855 804 847 831 874 718 741 703
> 789 756 688 825 824 748 875 697 676 798 747 705 736 765
> 858 717 745 863 876 823 865 704 719 732 800 880 767 759
> 842 815 753 779 680 833 752 734 716 696 851 834 682 708
> 844 758 772 884 828 737 795 754 829 797 827 lastStableBuild
> 850 714 886 774 887 762 883 860 707 687 739 861 805 722
> 763 859 845 817 822 864 821 749 699 746 802 711 857 867
> 740 684 698 692 760 832 693 830 839 806 750 738 728 678
> 818 710 727 701 888 849 729 843 841 744 764 814 872 766
> 808 712 854 695 810 881 731 862 878 713 816 848 720 777
> 700 lastUnstableBuild 775 769 742 791 866 694 725 796 770
> 773 879 685 787 809 legacyIds 690 856 799 838 768 730 803
> 793 677 686 683 807 743 lastFailedBuild 702 870 735 715 820
> lastSuccessfulBuild 835 836 785 733 776 706 786 781 788 709
> 790 868 689 882 869 840 755
> ________________After first removal_____________________________
> 778 761 794 792 885 877 811 873 871 679 726 771 837 691 783
> 751 813 780 852 723 721 801 826 784 757 846 812 782 724
> 855 804 847 831 874 718 741 703 789 756 688 825 824 748
> 875 697 676 798 747 705 736 765 858 717 745 863 876 823
> 865 704 719 732 800 880 767 759 842 815 753 779 680 833
> 752 734 716 696 851 834 682 708 844 758 772 884 828 737
> 795 754 829 797 827 675 850 714 886 774 887 762 883 860
> 707 687 739 861 805 722 763 859 845 817 822 864 821 749
> 699 746 802 711 857 867 740 684 698 692 760 832 693 830
> 839 806 750 738 728 678 818 710 727 701 888 849 729 843
> 841 744 764 814 872 766 808 712 854 695 810 881 731 862
> 878 713 816 848 720 777 700 819 775 769 742 791 866 694
> 725 796 770 773 879 685 787 809 681 690 856 799 838 768
> 730 803 793 677 686 683 807 743 853 702 870 735 715 820
> lastUnsuccessfulBuild 835 836 785 733 776 706 786 781 788
> 709 790 868 689 882 869 840 755
> ________________After second removal_____________________________
> 778 761 794 792 885 877 811 873 871 679 726 771 837 691 783
> 751 813 780 852 723 721 801 826 784 757 846 812 782 724
> 855 804 847 831 874 718 741 703 789 756 688 825 824 748
> 875 697 676 798 747 705 736 765 858 717 745 863 876 823
> 865 704 719 732 800 880 767 759 842 815 753 779 680 833
> 752 734 716 696 851 834 682 708 844 758 772 884 828 737
> 795 754 829 797 827 675 850 714 886 774 887 762 883 860
> 707 687 739 861 805 722 763 859 845 817 822 864 821 749
> 699 746 802 711 857 867 740 684 698 692 760 832 693 830
> 839 806 750 738 728 678 818 710 727 701 888 849 729 843
> 841 744 764 814 872 766 808 712 854 695 810 881 731 862
> 878 713 816 848 720 777 700 819 775 769 742 791 866 694
> 725 796 770 773 879 685 787 809 681 690 856 799 838 768
> 730 803 793 677 686 683 807 743 853 702 870 735 715 820
> 835 836 785 733 776 706 786 781 788 709 790 868 689 882
> 869 840 755


The only thing, which comes to my mind, is that the for loop has a maximum of iterations, but I could not found anything about it.

What is the explanation of this behavior? And is there a better solution to get just the directories with "number names". (I can't determine the number of directories.)

Answer

Well, don't change a list while iterating over it.

Use list comprehension:

listdir = [dir for dir in listdir if dir.isdigit()]
Comments