Hex dump of a list of 16-bit numbers
Here are some comments on your code:


I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0 is defined but never used
It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an if and the statement under condition.
/ performs a true division (giving a float). To avoid switching between float and int, use integer division: //
if i == 512: break could me omitted if you would limit the range of the for loop immediately. Instead of len(data) use min(512*16, len(data))
The multiplication i * 16 can be avoided if you use the step argument of range() so that i takes multiples of 16.
Instead of "%04x " % d use the newer f-strings
Instead of calculating d, you could just pass high and low to the string template and format each independently.
Instead of if (i % 16) == 15: you could use a nested loop that deals with one output line
Your code produces a blank at the end of each line. That seems unnecessary. With " ".join you would not have this extra blank.
out has a terminating \n, but print also prints a newline as terminator (by default). With "\n".joinyou would not have this extra newline


Here is how it could look:

# Set a maximum to the output
length = min(512*16, len(data))

# Format data
lines = []
for line in range(0, length, 256):
    items = []
    for i in range(line, min(line+256, length), 16):
        items.append(f"{data[i+1]:02x}{data[i]:02x}")
    lines.append(" ".join(items))
out = "\n".join(lines)

# Output
print(out)


Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability: 

# Format data
out = "\n".join([
            " ".join([
                f"{data[i+1]:02x}{data[i]:02x}"
                for i in range(line, min(line + 256, length), 16)
            ])
            for line in range(0, length, 256)
        ])