-1

I want to get a list of all images files.

imageExtensionList = ['jpg', '.arw', '.tif', 'mp4']
fileList = []
for extension in imageExtensionList:
    searchStr = str(importPath) + '/**/*.' + extension
    files = glob.glob(searchStr, recursive=True)
    fileList.append(files)

This however creates a list of lists. I want the files to be in a single list. There seem to be too many solutions in python for reducing/flattening of lists. How do I make a flat list out of a list of lists?

However, which should I apply to this list of strings?

which results in 'P:\Import/**/*.arw' So the windows and unix path are mixed. How can I correct this?

Matthias Pospiech
  • 3,130
  • 18
  • 55
  • 76
  • 1
    if you append a list to a list, **of course you get a list with a list in it**. You probably just want `.extend` instead of `.append`, which is equivalent to `for item in files: fileList.append(item)` so just use `fileList.extend(files)` – juanpa.arrivillaga Aug 30 '23 at 18:47
  • As an aside, "There seem to be too many solutions in python for reducing/flattening of lists." there is one canonical solution, I would say, which is `[x for sub in mylist for x in sub]`. – juanpa.arrivillaga Aug 30 '23 at 18:48
  • It seems like you have multiple questions here; canonicalizing your paths (or just normalizing the separator type) is a separate question from creating a separate unified list. Merging multiple distinct topics into one question frustrates attempts at having a single canonical answer per question, hence "too broad" as a close reason. – Charles Duffy Aug 30 '23 at 18:51
  • @juanpa.arrivillaga For me the canonical solution is `itertools.chain.from_iterable(mylist)`. Of course you have to wrap it in a call to `list` if you really need a list. – Matthias Aug 30 '23 at 19:17
  • @Matthias I just hate it because it's *sooo* wordy. They should have just had a seperate `itertools.flatten` that is simply `flatten = itertools.chain.from_iterable`. But I agree, it is a superior approach and I would prefer it if not for that verboseness. Python is a verbose language, certainly, it isn't terse. but the API design here makes it unnecessarily verbose. – juanpa.arrivillaga Aug 30 '23 at 19:18
  • @juanpa.arrivillaga Amen, brother! I agree. (and of course there is this little trick: `itertools.chain(*mylist)`) – Matthias Aug 30 '23 at 20:05
  • @Matthias yeah, but I hate that this requires creating an intermediate tuple when it is trivially unnecessary to. – juanpa.arrivillaga Aug 30 '23 at 20:22

1 Answers1

2

Of course, because that is what .append is supposed to do. You probably just want extend, so:

fileList.extend(files)

As an aside, since you mentioned it, the canonical way to create a flattened list is:

flattened = [item for sub in nested for item in sub]

This might inspire you to do this all in one go:

file_list = [
    file for ext in imageExtensionList
    for file in glob.glob(str(importPath) + '/**/*.' + extension, recursive=True)
]

But really, your approach with .extend is perfectly Pythonic.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • Ok `extent` work. The code for flattening is a typical example of what I do not like about pyhton - it is unreadable. I prever I function style like lists.reduce, lists.flat, Your approach to place everything in a list constructor is also a way I do not prefer, since it reduces code but makes is less readable. – Matthias Pospiech Aug 30 '23 at 19:11
  • @MatthiasPospiech it seems perfectly readable to me. ALthough, I agree, I would not prefer the large one. But note, that is a *list comprehension*, which is borrowed from Haskell, a purely functional language. So it is *extremely functinoal* – juanpa.arrivillaga Aug 30 '23 at 19:12
  • @MatthiasPospiech and note, that isn't a list constructor, that is a list comprehension, again, a functional programming construct. If you want a single function, you could use `import itertools` then use `itertools.chain.from_iterable(nested)`, you can even alias it, `flatten = itertools.chain.from_iterable`, but note, it returns an iterator, so if you want a list you can use `flattened = list(flatten(nested))` – juanpa.arrivillaga Aug 30 '23 at 19:14
  • @MatthiasPospiech but in any case, recall, the actual solution that is being advocated is for you just to use `.extend`, which seems pretty readable to me. – juanpa.arrivillaga Aug 30 '23 at 19:15