The xinttools package provides various loops, and among them there is \xintFor which iterates over a comma separated lists of items (possibly represented as macro). The package can be used either with Plain Tex:
\input xinttools.sty
or with LaTeX
\usepackage{xinttools}
Loading and usage is possible without the Plain format loaded as long as:
for loading of the package: the % is of category code comment character, the \ is of category code escape character, digits have category code other, letters have category code letter,
for usage of \xintFor: {, }, , and # all have their standard category code, and the \empty and \space macros their standard meanings.
The syntax is:
\xintFor #1 in {\mylist} \do {stuff with #1}
The #1 (or #2, ..., #9: this is to allow nesting with the iterated text using itself a further \xintFor) is treated as in the replacement text of a macro with parameter, thus if \list expands to, or is, abc, def, ghk then #1 will be abc then def then ghk not a macro expanding to these things.
When \xintFor is used inside a macro definition, the # must be doubled as usual: ##1. There will be no conflict if this macro once defined is used elsewhere, for example inside another \xintFor loop defined itself with a #1 or ##1.
The \xintFor is not expandable, that means one can not insert it inside an \edef. However it has been especially designed to be usable inside alignments such as a tabular.
\documentclass{article}
\usepackage{xinttools}
\begin{document}
\begin{tabular}{ccc}
\hline
\xintFor #1 in {A, B, C, D, E}\do {#1&\lowercase{#1}&\textbf{#1}\\}
\hline
\end{tabular}
\end{document}

Although the loop survives the closing of groups possibly done by its replacement text (as is the case in the example above), it does not make by itself any global assignment.
- How does the command/method deal with whitespace around items?
It removes them, both starting and trailing spaces (the case of multiple space tokens, of standard character code 32, is also handled). Additionally if the item was ...,<spaces>{item}<spaces>,..., one level of brace pair is removed (but spaces inside the braces are left untouched). In the special case ...,{stuff},.. of a braced item with no spaces to separate both commas from braces, stuff will also be stripped of starting and trailing spaces.
- How does the command/method deal with empty/missing items? (e.g. a,b,,c)
A missing item is treated as empty item. That is #1 is empty. The iteration is not skipped.
- How does the command/method deal with a trailing comma?
A trailing comma means a trailing empty item. One can use \xintifForLast to abort the loop if one knows the list has such an empty ending item!
- Can the command/method work of a list stored on a macro?
Yes. \xintFor #1 in \list \do, \xintFor #1 in {\list} \do, \xintFor #1 in {a,b,c} \do are equivalent (if the macro \list expanding to a,b,c has arguments, braces around it and its arguments must be used). And \list is expanded exactly once. With in {\x,a,b,c} as input, \x will be expanded, and may for example transform the list into {d,e,f,a,b,c}. Use {{\x},a,b,c} or { \x,a,b,c} to prevent this expansion of \x (in the latter form, the initial space is gobbled and serves only to prevent expansion of \x). For all other items except the first, there will never be any expansion.
- Is each iteration evaluated globally or on a local group? (i.e., if a command is defined during an iteration, does the command survive the loop?)
No global assignments is made. No local group is created. Yes, if a command is defined during the iteration it will survive the loop: assuming the iteration text does not itself close groups!
- Do items get expanded or somehow mangled before being processed?
Spaces at the starts and ends are stripped, and exactly one level of braces is removed. The first item will get expanded if it is not protected by braces or an intial space and if the list is not given as macro but directly.
- What about lists where items are key=value or some other kind of pairs?
\xintFor only looks at commas, thus the #1 will be key=value.
- Does the method work for lists separated with something other than a comma?
No, \xintFor is only for comma separated lists (with a standard category code comma). \xintFor converts the comma separated list to a sequence of braced stripped items using \xintCSVtoList and then treats this sequence with \xintFor*.
- Any other thing I should know before deciding to use this method?
The comma separated items may contain \par or empty lines.
\xintFor has been designed to:
- be usable within alignments,
- allow nesting (up to nine levels),
- not use macros to encapsulate the items but manipulate them as usual macro parameters,
- not create groups.
The xint documentation provides some more information.
The package does not provide facilities to manipulate comma separated lists per se, only to use them.
Expandable manipulations are possible via first converting with \xintCSVtoList the comma separated list to a sequence of braced items ({abc}{123}...) and then using \xintApply or \xintApplyUnbraced which apply a given one-argument macro in turn to each item of the sequence. Also, \xintNthElt accesses the element of given index (either from the start or end, if negative), but the package is lacking currently facilities to cut and glue such sequences of braced items, perhaps this will be added.
The iteration done by \xintFor can be prematurely interrupted using \xintBreakFor and \xintBreakForAndDo inside the replacement text, for example in the YES or NO branch of some LaTeX-like test, the package own tests, or the etoolbox tests, or some ifthen test (non-expandability not being an issue).
\xintifForFirst {stuff if first iteration}{stuff if not first}, \xintifForLast {stuff if last iteration}{stuff is not last iteration}, allow special treatment of the first or last iterations; but to count iterations the user is invited to define a counter or \count and update it as part of the loop (if used in an alignment, presumably the \count assignments will need to be made global).